算法设计与分析(六):Graph And Tree

Is Subsequence

Given a string s and a string t, check if s is subsequence of t.
You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and s is a short string (<=100).
A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, “ace” is a subsequence of “abcde” while “aec” is not).

Example 1:
s = "abc", t = "ahbgdc"

Return true.
Example 2:
s = "axc", t = "ahbgdc"

Return false.


这题很简单,就是要求一个字符串中是否由另一个子字符串。这里对子字符串的定义是:子字符串中的字母是否均按原顺序出现在另一个字符串中。

在一个字符串t中,当然可能出现字符串s序列的地方不止一处。由于我们只需要知道有没有,而不需要知道有几次,我们可以按照贪心算法的思路,以下面的一种思路来寻找“第一次”出现的子字符串s:

符合条件的字符串t,就是s中的每个字符x后面的那个字符y,在字符串t中选取为匹配的字符x之后也必须存在一个字符y。为了尽量“贪心”,我们取第一次出现的为相同字符为匹配字符,这样留个后面的选择空间最大。

注意考虑字符串的特殊情况,即当s或者t为空字符串的时候,解是什么;显然,当s为空时,结果必然为真;当t为空而s不为空时,结果必然为假:

if(s.length() == 0) return true;
if(t.length() == 0) return false;

遍历整个s,对其中的每个字符,搜寻t寻找匹配,而每次搜寻的起点就是上一个匹配字符的位置,即上一次搜寻的终点。
如果s的最后一个字符都找到了匹配,那么结果为真;否则,结果为假。
最后整个s和t都会被遍历一遍,所以时间复杂度应为O(s+t)。

附上完整C++代码:

class Solution {
public:
    bool isSubsequence(string s, string t) {
        
        int pos = 0;
        if(s.length() == 0) return true;
        if(t.length() == 0) return false;
        
        for(int i = 0;i < s.length() ; i++) {
            for(int j = pos;j < t.length(); j ++) {
                if(s[i] == t[j]) {
                    if(i == s.length()-1) return true;
                    else {
                        pos = j + 1;
                        break;
                    }
                }
                if(j == t.length()-1) return false;
            }
        }
        return false;
    }
};

附上LeetCode链接:https://leetcode.com/problems/is-subsequence/description/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值