判断子序列[简单]

news2024/9/20 10:51:04

优质博文:IT-BLOG-CN

一、题目

给定字符串st,判断s是否为t的子序列。字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如aceabcde的一个子序列,而aec不是)。

进阶: 如果有大量输入的S,称作S1,S2,..., Sk其中k >= 10亿,你需要依次检查它们是否为T的子序列。在这种情况下,你会怎样改变代码?

示例 1:
输入:s = "abc", t = "ahbgdc"
输出:true

示例 2:
输入:s = "axc", t = "ahbgdc"
输出:false

0 <= s.length <= 100
0 <= t.length <= 10^4
两个字符串都只由小写字符组成。

二、代码

【1】双指针: 初始化两个指针ij,分别指向st的初始位置。匹配成功则ij同时右移,匹配s的下一个位置,匹配失败则j右移,i不变,尝试用t的下一个字符匹配s。最终如果i移动到s的末尾,就说明st的子序列。

class Solution {
    public boolean isSubsequence(String s, String t) {
        // 定义两个双指针进行移动, 如果指针指向的位置相同,两个指针指向下一位,如果不相同,s指针移动一位
        int sIndex = 0, tIndex = 0;
        while (tIndex < t.length() && sIndex < s.length()) {
            if (t.charAt(tIndex) == s.charAt(sIndex)) {
                ++sIndex;
            }
            ++tIndex;
        }
        return sIndex == s.length();
    }
}

时间复杂度: O(n+m)其中ns的长度,mt的长度。每次无论是匹配成功还是失败,都有至少一个指针发生右移,两指针能够位移的总距离为n+m
空间复杂度: O(1)

【2】动态规划: 我们可以预处理出对于t的每一个位置,从该位置开始往后每一个字符第一次出现的位置。我们可以使用动态规划的方法实现预处理,令f[i][j]表示字符串t中从位置i开始往后字符j第一次出现的位置。在进行状态转移时,如果t中位置i的字符就是j,那么f[i][j]=i,否则j出现在位置i+1开始往后,即f[i][j]=f[i+1][j],因此我们要倒过来进行动态规划,从后往前枚举i

这样我们可以写出状态转移方程:

假定下标从0开始,那么f[i][j]中有0≤i≤m−1,对于边界状态f[m−1][..],我们置f[m][..]m,让f[m−1][..]正常进行转移。这样如果f[i][j]=m,则表示从位置i开始往后不存在字符j

这样,我们可以利用f数组,每次O(1)地跳转到下一个位置,直到位置变为ms中的每一个字符都匹配成功。

同时我们注意到,该解法中对t的处理与s无关,且预处理完成后,可以利用预处理数组的信息,线性地算出任意一个字符串s是否为t的子串。这样我们就可以解决「后续挑战」啦。

class Solution {
    public boolean isSubsequence(String s, String t) {
        int n = s.length(), m = t.length();

        int[][] f = new int[m + 1][26];
        for (int i = 0; i < 26; i++) {
            f[m][i] = m;
        }

        for (int i = m - 1; i >= 0; i--) {
            for (int j = 0; j < 26; j++) {
                if (t.charAt(i) == j + 'a')
                    f[i][j] = i;
                else
                    f[i][j] = f[i + 1][j];
            }
        }
        int add = 0;
        for (int i = 0; i < n; i++) {
            if (f[add][s.charAt(i) - 'a'] == m) {
                return false;
            }
            add = f[add][s.charAt(i) - 'a'] + 1;
        }
        return true;
    }
}

时间复杂度: O(m×∣Σ∣+n),其中ns的长度,mt的长度,Σ为字符集,在本题中字符串只包含小写字母,∣Σ∣=26。预处理时间复杂度O(m),判断子序列时间复杂度O(n)

如果是计算k个平均长度为n的字符串是否为t的子序列,则时间复杂度为O(m×∣Σ∣+k×n)

空间复杂度: O(m×∣Σ∣)为动态规划数组的开销。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1482065.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

html样式排版

<template><div class"box"><div class"header">头部</div><div class"main"><div class"left">菜单</div><div class"right"><div class"right-contentr"&g…

C++菱形继承_多态

&#x1f493;博主CSDN主页:麻辣韭菜-CSDN博客&#x1f493;   ⏩专栏分类&#xff1a;http://t.csdnimg.cn/362T6⏪   &#x1f69a;代码仓库:要相信光/C高阶&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多C知识   &#x1f51d;&#x1f51d; 目录 前言…

容联云入选IDC生成式AI图谱,多个案例被评典型应用

随着生成式AI进入商业化初期&#xff0c;国际数据公司&#xff08;IDC&#xff09;于近日发布了《IDC Market Glance: 中国生成式AI市场概览》报告&#xff0c;报告分析了当前市场的整体情况以及市场格局&#xff0c;通过中国生成式AI市场生态图谱V1.0和代表厂商分析&#xff0…

BUUCTF---另外一个世界1

1.这是一道杂项题&#xff0c;也是我觉得最值得记录的一道题。 2.话不多说&#xff0c;题目描述&#xff08;真的是另一个世界&#xff09; 3.下载附件&#xff0c;是一张图片 4.尝试了查看属性&#xff0c;以及在记事本中打开看看有没有什么有用的信息&#xff0c;发现没什么…

C# WPF如何自定义控件ComboBox

在WPF开发中&#xff0c;经常遇到需要修改原生ComboBox的控件样式。 对于新手来说&#xff0c;修改控件样式比较麻烦。 修改的最终样式如下&#xff1a; 你可以利用如下代码模板&#xff0c;修改为你自己想要的样式。 <Style TargetType"{x:Type ComboBox}"&…

CSP-202112-3-登机牌条码

CSP-202112-3-登机牌条码 解题思路 一、.处理大小写和数字 初始化变量&#xff1a;flag: 用来标识当前处理的字符类型&#xff0c;0代表大写字母&#xff0c;1代表小写字母&#xff0c;2代表数字。 大小写字母和数字的处理&#xff1a; 小写字母(a < it && it &l…

新一代湖仓集存储,多模型统一架构,高效挖掘数据价值

星环科技TDH一直致力于给用户带来高性能、高可靠的一站式大数据基础平台&#xff0c;满足对海量数据的存储和复杂业务的处理需求。 同时在易用性方面持续深耕&#xff0c;降低用户开发和运维成本&#xff0c;让数据处理平民化&#xff0c;助力用户以更便捷、高效的方式去挖掘数…

基带信号处理设计原理图:2-基于6U VPX的双TMS320C6678+Xilinx FPGA K7 XC7K420T的图像信号处理板

基于6U VPX的双TMS320C6678Xilinx FPGA K7 XC7K420T的图像信号处理板 综合图像处理硬件平台包括图像信号处理板2块&#xff0c;视频处理板1块&#xff0c;主控板1块&#xff0c;电源板1块&#xff0c;VPX背板1块。 一、板卡概述 图像信号处理板包括2片TI 多核DSP处理…

anaconda简介以及安装(Windows)

介绍 Anaconda是一个开源的Python发行版本&#xff0c;它是一个打包的集合&#xff0c;里面预装了conda、Python、众多packages、科学计算工具等。Anaconda的目的是方便使用Python进行数据科学研究&#xff0c;它涵盖了数据科学领域常见的Python库&#xff0c;并且自带了专门用…

Linux之gcc和makefile的使用详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 算法 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.gcc/g安装 二.gcc运行代码 三.gcc是如何完成的 3.1预处…

matlab图像仿射变换

在Matlab中进行图像的仿射变换通常使用imwarp函数。下面是一个简单的示例代码&#xff0c;以及对应的说明&#xff1a; % 读取图像 image imread(lena.png);% 设置仿射变换矩阵 theta 30; % 旋转角度 scale_factor 1.5; % 缩放因子 shear_factor 0.5; % 剪切因子% 构造仿射…

Ps:海绵工具

海绵工具 Sponge Tool可用于调整图像中特定区域的饱和度&#xff0c;常用于增加或减少颜色的饱和度。 快捷键&#xff1a;O 在特别的灰度图像上&#xff0c;则可用于调整对比度&#xff0c;这可以开发出更多的创意技巧。 ◆ ◆ ◆ 常用操作方法与技巧 1、海绵工具主要用于调整…

二百二十五、海豚调度器——用DolphinScheduler调度执行Flume数据采集任务

一、目的 数仓的数据源是Kafka&#xff0c;因此离线数仓需要用Flume采集Kafka中的数据到HDFS中 在实际项目中&#xff0c;不可能一直在Xshell中启动Flume任务&#xff0c;一是项目的Flume任务很多&#xff0c;二是一旦Xshell页面关闭Flume任务就会停止&#xff0c;这样非常不…

【数据结构与算法】动态规划法解题20240302

这里写目录标题 一、198. 打家劫舍1、动态规划五部曲 二、213. 打家劫舍 II 一、198. 打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间…

iOS消息发送流程

Objc的方法调用基于消息发送机制。即Objc中的方法调用&#xff0c;在底层实际都是通过调用objc_msgSend方法向对象消息发送消息来实现的。在iOS中&#xff0c; 实例对象的方法主要存储在类的方法列表中&#xff0c;类方法则是主要存储在原类中。 向对象发送消息&#xff0c;核心…

vscode 引入外部依赖包

背景 我要在vscode中写一些antlr代码生成的cpp代码&#xff0c;但是在引入头文件#include "antlr4-runtime.h"的时候&#xff0c;出现报错&#xff0c;显示没有这个头文件&#xff0c;显然这是我们没有导入相关的包&#xff0c;因此我首先尝试了将antlr4的依赖源码在…

超链接和导航:网页互动的艺术

引言 在上一篇文章中&#xff0c;我们探索了HTML中多媒体的交互体验&#xff0c;本次我们将学习如何通过超链接和导航栏提升网页的用户体验&#xff0c;让用户在网页访问时更高效&#xff1b; 一、介绍 在这个信息爆炸的时代&#xff0c;如何让用户在第一时间找到他们需要的信…

相机格式化了还能恢复照片吗?内存卡数据恢复方法

相机已成为我们记录生活、工作和学习的重要工具。然而当相机意外格式化后&#xff0c;许多珍贵的照片可能会瞬间消失&#xff0c;这无疑给我们的生活和工作带来不小的困扰。那么相机格式化后&#xff0c;我们是否还有机会找回那些丢失的照片呢&#xff1f; 首先我们需要了解相机…

CSS的弹性布局

CSS 的弹性布局 前言 前端中为了实现页面的布局效果&#xff0c;采用的一个技术手段&#xff0c;它在前端开发的技术场景是非常广泛的 实现上述区域的页面相关的布局效果&#xff0c;就可以使用弹性布局来完成 弹性布局(flex布局) flex 是 flexible box 的缩写&#xff0c;…

ChromeDriver全版本下载教程

确定自己的Chrome版本 step1. 打开Chrome浏览器右上角的三个点&#xff0c;再点击设置 step2. 在设置中点击“关于Chrome”&#xff0c;圈起来的红框即为当前Chrome版本&#xff0c;我的版本就是121.0.6167.185 在json中查找自己对应ChromeDriver版本下载链接 一般教程会让你…