LeetCode Daily Challenge Is Subsequence

题目大意

判断一个字符串s是否是另一个串t的子序列。子序列指将一个字符串删除若干字符后组成的串。例如abcassdfbsc的子序列。输入限制:

  • 0 <= s.length <= 100
  • 0 <= t.length <= 10^4
  • 两个字符串都只包含小写字母

进阶:假如有超过10亿个s串,一个t串,怎么做会更好。

思路

对于一个st来说,可以直接从前往后判断,考虑s中的字符在t中最早出现位置即可。但是假如s数目较大的话,一个一个判断就不能很好的利用t只有一个的特性,因此可以利用最早出现位置的特性优化。

由于字符串中只包含小写字母,而t.length <= 10^4,因此可以打表记录每个小写字母的出现位置。流程如下:

有效起始位置 = -1
对i从0到1
    判断s[i]是否在 有效起始位置 后出现过 (二分查找)
        未出现过 -> false
    更新 有效起始位置 为s[i]出现的位置
true

判断是否出现过可以利用位置一定是从小到大的特性使用二分查找,对应STL中的upper_bound

另外就是边界情况:

  • s.size() = 0
  • t.size() = 0
  • 对于s[0],有效起始位置 应为 -1
  • s=aaaaaa,t=bbaaaa的情况(使用upper_bound而不是lower_bound)

代码

class Solution {
public:
    bool isSubsequence(string s, string t) {
        if (s.size() <= 0)
            return true;
        const int sz = t.size();
        if (sz <= 0)
            return false;
        vector<vector<int>> table(26);
        for (int i = 0; i < sz; i++) {
            table[t[i] - 'a'].push_back(i);
        }
        int laPos = -1;
        for (size_t i = 0; i < s.size(); i++) {
            const char sc = s[i];
            const int sci = sc - 'a';
            auto it = upper_bound(table[sci].begin(), table[sci].end(), laPos);
            if (it == table[sci].end()) 
                return false;
            laPos = *it;
        }
        return true;
    }
};

总结

打表+二分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值