【Swift算法学习】 LeetCode 392 判断子序列

题目

LeetCode 392 判断子序列

给定字符串 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

    }
}

总结

这里主要还是要考虑清楚,为什么双指针一次就可以完成遍历,并且保证能包含所有的结果。

你可能感兴趣的:(算法学习,leetcode,算法,学习)