题目概述
大意就是给两个字符串s和t,判断s是否是t的子串(不要求s在t中连续),如果是返回true,如果不是返回false(原题链接)
例如:
- abc是ahbgde的子串
- amc不是ahbgde的子串
难度级别:easy
解题思路
既然是判断s是否为t的子串,容易想到的就是拿s中每一个字符去跟t的字符进行比较,那么需要做的就是设置两个变量(可理解为指针),如下图所示:
- 初始化
- 可以看出第一个字母即匹配成功,则同时移动指针i和指针j
- 从第二步可以看出,指针i所指(b)和指针j所指(h)不匹配,那么移动j直到匹配到相应字符或者到达字符串T边界停止
- 此例较为凑巧,移动至字符串T边界匹配成功
可以看出,我们需要做的就是每次固定指针i,通过移动指针t,即可判断s中到i截止的子串是否是t的子串,终止条件即为i遍历为完或者j遍历完(有且仅有以下三种情况:如果i遍历完,j未遍历完,那么匹配成功;如果i为遍历完,j遍历完,那么匹配不成功;如果i遍历完,j也遍历完,那么匹配成功)
代码
注意:代码1在LeetCode平台会报错,原因找了很久没找到,可能原因是时间复杂度太高,导致报Runtime Error
,但在本地测试报错的输入时符合题意
代码1和代码2的主要区别在于判断指针移动的方式不同,代码1是直到找到s[i]==t[j]
的情况下指针j才进行移动,然后指针i进行移动,即主要考虑指针j的移动。代码2则是当找到相同字符后,两个指针同时进行移动,即主要考虑指针i和指针j的移动
PS:我也不知道为什么当时脑抽非要用代码1的思路,时间复杂度还高那么多,后来没办法一直报错,只能小改以下思考角度。。。
代码1(慎用)
bool isSubsequence(string s, string t) {
if(s.empty()) return true;
int i=0,j=0;
bool flag = true;
while(i < s.length() || j < t.length()){
while(t[j] != s[i]){
j++;
if(j >= t.length()){
flag = false;
break;
}
}
i++;
if(j < t.length()) j++;
if(i >= s.length()) break;
}
return flag;
}
代码2(推荐)
bool isSubsequence(string s, string t) {
if(s.empty()) return true;
int i=0,j=0;
bool flag = true;
while(i < s.length() && j < t.length()){
if(s[i] == t[j]){
i++;
j++;
}else{
j++;
}
}
if(i == s.length()) return true;
return false;
}