題目描述:
給定字符串 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 的子序列。在這種情況下,你會怎樣改變代碼?
致謝:
特別感謝 @pbrother 添加此問題並且創建所有測試用例。
首先不考慮後續挑戰,比較簡單:
代碼:
class Solution {
public boolean isSubsequence(String s, String t) {
int starts = 0;
int startt = 0;
char tems[] = s.toCharArray();
char temt[] = t.toCharArray();
while (starts < tems.length && startt < temt.length) {
if(tems[starts] == temt[startt]){
starts ++;
startt ++;
continue;
}
startt ++;
}
if(starts == tems.length){
return true;
}
return false;
}
}
後續挑戰
可以考慮使用索引,從s中依次找每個字符的索引,每次開始的時候從index開始,index初始值爲-1
class Solution {
public boolean isSubsequence(String s, String t) {
int index = -1;
for (char c : s.toCharArray()){
index = t.indexOf(c, index+1);
if (index == -1) return false;
}
return true;
}
}
後續挑戰,輸入量大,小寫字母創建25的二維數組,存儲t的座標,這樣就可以把s的判斷直接轉爲座標的判斷,
dp[0]代表了存儲了a出現在t的所有的位置,逐個字符判斷s的字符順序是否在t內,直接返回結果。
時間複雜度O(t.size()+2000):分別爲創建數組需要O(t.size()),
索引是遞增的使用二分查找s的單個字符20次之內就可找到需要O(100*20)。
適用大量的輸入判斷子序列。
bool isSubsequence(string s, string t) {
vector<vector<int>>dp(26);
int tag=-1;
for(int i=0;i<t.size();i++)
dp[t[i]-'a'].push_back(i);
for(int i=0;i<s.size();i++){
int now=s[i]-'a';
int left=0,right=dp[now].size()-1;
while(left<right){
int mid=(left+right)/2;
if(dp[now][mid]>tag)
right=mid;
else
left=mid+1;
}
if(right<left || dp[now][left]<tag)return false;
tag=dp[now][left];
}
return true;
}
作者:zzzzzz-5
鏈接:https://leetcode-cn.com/problems/is-subsequence/solution/cpan-duan-zi-xu-lie-hou-xu-tiao-zhan-by-zzzzzz-5/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。