判斷子序列
題目描述:給定字串 s 和 t ,判斷 s 是否為 t 的子序列。
字串的一個子序列是原始字串刪除一些(也可以不刪除)字元而不改變剩餘字元相對位置形成的新字串。(例如,"ace"是"abcde"的一個子序列,而"aec"不是)。
進階:
如果有大量輸入的 S,稱作 S1, S2, ... , Sk 其中 k >= 10億,你需要依次檢查它們是否為 T 的子序列。在這種情況下,你會怎樣改變程式碼?
示例說明請見LeetCode官網。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/probl...
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
解法一:雙指標遍歷
首先,判斷幾種特殊場景:
- 如果s子串為空,則s一定是t的子序列,直接返回true;
- 如果s不為空,t為空,則s不可能是t的子序列,直接返回false;
- 如果s子串的長度大於t的長度,則s不可能是t的子串,直接返回false。
如果不是特殊情況,則使用雙指標分別指向s和t的第一個字元,然後遍歷s和t的字元,遍歷過程如下:
- 如果s還未遍歷的字串長度大於t還未遍歷的字串長度,則s不可能是t的子串,直接返回false;
- 如果s和t當前位置的字元相同,則指標同時往後移動一位;
- 如果s和t當前位置的字元相同,則指向t的指標往後移動一位;
- 遍歷結束的條件就是s或t遍歷到最後一位。
最後,判斷如果s遍歷完成,說明s是t的子序列,返回true;否則,返回false。
public class LeetCode_392 {
/**
* 雙指標
*
* @param s
* @param t
* @return
*/
public static boolean isSubsequence(String s, String t) {
/**
* 如果s子串為空,則s一定是t的子序列,直接返回true
*/
if (s == null || s.length() == 0) {
return true;
}
// 如果s不為空,t為空,則s不可能是t的子序列,直接返回false
if (t == null || t.length() == 0) {
return false;
}
// 如果s子串的長度大於t的長度,則s不可能是t的子串,直接返回false
if (s.length() > t.length()) {
return false;
}
// 分別指向s和t的第一個字元
int sIndex = 0, tIndex = 0;
// 一個個的遍歷字元,直到遍歷到s或t的最後一個字元
while (sIndex < s.length() && tIndex < t.length()) {
// 如果s還未遍歷的字串長度大於t還未遍歷的字串長度,則s不可能是t的子串,直接返回false
if (s.length() - sIndex > t.length() - tIndex) {
return false;
}
// 如果s和t當前位置的字元相同,則指標同時往後移動一位
if (s.charAt(sIndex) == t.charAt(tIndex)) {
sIndex++;
tIndex++;
} else {
// 如果s和t當前位置的字元相同,則指向t的指標往後移動一位
tIndex++;
}
}
// 最後,如果s遍歷完成,說明s是t的子序列,返回true
if (sIndex == s.length()) {
return true;
}
return false;
}
public static void main(String[] args) {
// 測試用例,期望返回: true
System.out.println(isSubsequence("abc", "ahbgdc"));
}
}
【每日寄語】 站起來做人,彎下腰做事。