1. 程式人生 > >leetcode392. 判斷子序列

leetcode392. 判斷子序列

題目:

給定字串 s 和 t ,判斷 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 >= 10億,你需要依次檢查它們是否為 T 的子序列。在這種情況下,你會怎樣改變程式碼?

思路:

順著字串t走一遍,用一個指標j指向s,如果在走t的時候發現與s的第j個字元相同,那麼j後移一位,知道t中有一個字元與其匹配。如果最後能到s的結尾,則說明有解。時間複雜度O(len(s)+len(t))

如果k多到了十億的程度,如果每次都需要遍歷T的話,效率會比較低。那麼可以統計t每個字元出現的位置,把每一個字元出現的位置從小到大都記錄在一個數組裡面。然後遍歷s,對於s[i],二分s[i]對應的那個陣列找到符合要求的最小位置。這裡的要求就是,該位置需要比s[i-1]找到的位置大。如果找不到就false效率為k*len(M)*log(len(t)),提高了百倍左右的效率。

程式碼:

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

};