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;
    }
};

總結

打表+二分。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章