给定字符串 s 和字符串 t,判断 s 是否是 t 的子序列。

两个字符串均只包含小写英文字母。t 可能非常长(长度约 500,000),s 较短(长度 <= 100)。

子序列是指从原字符串中删除若干字符(也可以不删除),且不改变剩余字符相对顺序而得到的新字符串。例如,"ace" 是 "abcde" 的子序列,而 "aec" 不是。

示例

  • 示例 1:s = "abc",t = "ahbgdc",返回 true。
  • 示例 2:s = "axc",t = "ahbgdc",返回 false。

进阶:如果有大量的 S 需要判断(S1, S2, …, Sk,k >= 1B),每次都要判断是否是 T 的子序列,如何优化代码?

可以使用 DP、贪心或二分查找来解决本题。

方法一:线性扫描(贪心)

最简单的做法:只需扫描 t 一遍,用一个指针跟踪 s 的匹配进度即可。

if (s == "")return true;
                
                		int index = 0;
                		for (int i = 0; i < t.size(); i++)
                		{
                			if (s[index] == t[i])
                			{
                				index++;
                				if (index >= s.size())return true;
                			}
                
                
                		}
                
                		return false;

方法二:暴力递归搜索

bool f(int a, int b)
                {
                	if (sa =="" )return true;
                
                	if (a > sa.size())return true;//如果大于 那么表示前面所有的都匹配了因此true
                
                	if (b > sb.size())return false;//b的index大于大小,意味着搜索完了还没return true因此false
                
                	if (sa[a] == sb[b])//如果相同 那么直接递归下一个index
                	{
                		return f(a + 1, b + 1);
                	}
                	else
                	{
                		return    f(a, b + 1);//不同则移动sb的index
                	}
                }

方法三:将暴力递归转换为 DP

递推公式与递归公式相同,但循环方向需要逆向——因为递归是从底部返回的,所以递推要倒着来。

bool arr[10][10];//a b
                	memset(arr, 0, 10 * 10);
                
                
                	for (int b = 0; b < 10;b++)arr[0][b] = true;//初始化 字符串空
                
                	for (int a = sa.size(); a < 10; a++)
                	{
                		for (int b =0; b < 10; b++)
                		arr[a][b] = true; // 初始化a>sa.size的情况
                	}
                	for (int a =  sa.size() - 1;a>=0; a--)//递推求解,递推公式和递归公式一样,但是循环条件是逆向,因为递归到底以后是倒着返回来的,所以递推要倒着
                	{
                		for (int b = sb.size() - 1;b>=0; b--)
                		{
                			if (sa[a] == sb[b])
                			{
                				arr[a][b] = arr[a + 1][b + 1];
                			}
                			else
                			{
                				arr[a][b] = arr[a][b + 1];
                			}
                		}
                	}
                
                
                	cout << arr[0][0] << endl;
                	cout << f(0, 0) << endl;