给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
致谢:
特别感谢 @pbrother 添加此问题并且创建所有测试用例。
示例 1:
输入:s = “abc”, t = “ahbgdc”
输出:true
示例 2:
输入:s = “axc”, t = “ahbgdc”
输出:false
首先这道题特别考验读题能力,这子序列并不代表子串,比如"abc" 是 "abdc"的子序列,但并不是"abdc"的子串,也就是说,"abc"只要按顺序排列在"abdc"中即可,不需要是连续的排列,这就为双指针写法提供了前提
这里我们用两个指针,分别指向两个string的开头位置,然后不断+1,判断s中的字符是否出现在t中,知道遍历完成任意一个
这里之所以能这么做一次遍历就能完成的原因是如果s中的字符a出现在了t中,无论出现了几次,其第一次出现已经满足了子序列的要求,所以无须遍历后续的值,比如"ab" 和"aabc", “aabc” 中的第一个已经满足了a,第二个满足a的就不再会用到了,所以只需要遍历一次就可以完成整个算法
class Solution {
func isSubsequence(_ s: String, _ t: String) -> Bool {
let characterS = Array(s)
let characterT = Array(t)
var i = 0, j = 0
while (i < characterS.count && j < characterT.count) {
if(characterS[i] == characterT[j]){
i += 1
j += 1
} else {
j += 1
}
}
return i == characterS.count
}
}
这里主要还是要考虑清楚,为什么双指针一次就可以完成遍历,并且保证能包含所有的结果。