leetcode392--判断子序列

2024-04-30 16:04
文章标签 判断 序列 leetcode392

本文主要是介绍leetcode392--判断子序列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 题意

判断字符串 s s s是否为 t t t的子序列

2. 题解

2.1 双指针

对于在 t t t中找到的 s [ i ] s[i] s[i]字符,我们只需要找下一个即可。

即一个指针 i i i指向 s s s,一个指针 j j j指向 t t t;

  • s [ i ] = = t [ j ] , i ← i + 1 , j ← j + 1 s[i] ==t[j], i \leftarrow i+1,j \leftarrow j+1 s[i]==t[j],ii+1,jj+1
  • s [ i ] ≠ t [ j ] , i ← i + 1 s[i] \ne t[j], i \leftarrow i+1 s[i]=t[j],ii+1

代码

class Solution {
public:bool isSubsequence(string s, string t) {int slen = s.size();int tlen = t.size();if ( slen > tlen)return false;int i = 0;int j = 0;while ( i < slen && j < tlen ) {if (s[i] == t[j])++i,++j;else {++j;}}return i == slen; }
};
2.2 双指针+预处理

我们可以预处理 j j j,当 s [ i ] ≠ t [ j ] s[i]\ne t[j] s[i]=t[j], j j j跳到下一个邻近 s [ i ] s[i] s[i]表示字符出现的位置。

预处理我们可以从后往前遍历;得到转移方程

d p [ i ] [ j ] = { d p [ i + 1 ] [ j ] , c = = ′ a ′ + j i , c ≠ ′ a ′ + j dp[i][j]= \begin{cases} dp[i+1][j], \quad c == 'a'+j\\ i, \quad c \ne 'a'+j \end{cases} dp[i][j]={dp[i+1][j],c==a+ji,c=a+j

d p [ i ] [ j ] dp[i][j] dp[i][j]表示在字符串 t t t中的 i i i位置与其右端最邻近的 j + ′ a ′ j +'a' j+a字符的位置。

这个dp数组的作用,是来加速上面双指针中 j j j指针的跳转。


class Solution {
public:bool isSubsequence(string s, string t) {int n = s.size();int m = t.size();vector<vector<int>> dp(m + 1, vector<int>(26, m));for (int i = m - 1; ~i ; --i) {for (int j = 0;j < 26; ++j) {if ( j + 'a' == t[i]) {dp[i][j] = i;}else {dp[i][j] = dp[i + 1][j];}}}int i = 0;int j = 0;while (i < n && j < m) {if (s[i] == t[j]) {i++;j++;}else {j = dp[j][s[i] - 'a'];}}return i == n; }
};
2.3 动态规划

可以转换为经典的 L C S ( l o n g e s t c o m m o n s e q u e n c e ) LCS(longest\ common\ sequence) LCS(longest common sequence)最长公共子序列问题,

L C S ( s , t ) = s . s i z e ( ) LCS(s,t) =s.size() LCS(s,t)=s.size()

class Solution {
public:bool isSubsequence(string s, string t) {if (s.empty())return true;int m = static_cast<int>( s.size() );int n = static_cast<int>( t.size() );vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));for (int i = 1;i <= m; ++i) {for ( int j = 1; j <= n; ++j) {if (s[i - 1] == t[j - 1])dp[i][j] = dp[i - 1][j - 1] + 1;elsedp[i][j] = max( dp[i][j - 1], dp[i - 1][j]);}}return dp[m][n] == m;}
};

这篇关于leetcode392--判断子序列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/949301

相关文章

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

关于最长递增子序列问题概述

《关于最长递增子序列问题概述》本文详细介绍了最长递增子序列问题的定义及两种优化解法:贪心+二分查找和动态规划+状态压缩,贪心+二分查找时间复杂度为O(nlogn),通过维护一个有序的“尾巴”数组来高效... 一、最长递增子序列问题概述1. 问题定义给定一个整数序列,例如 nums = [10, 9, 2

Python判断for循环最后一次的6种方法

《Python判断for循环最后一次的6种方法》在Python中,通常我们不会直接判断for循环是否正在执行最后一次迭代,因为Python的for循环是基于可迭代对象的,它不知道也不关心迭代的内部状态... 目录1.使用enuhttp://www.chinasem.cnmerate()和len()来判断for

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;