• 【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
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    总结

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

  • 相关阅读:
    Vue3新的状态管理库-Pinia(保姆级别教程)
    python 检测文本语言类型
    Revit翻模技巧丨怎么一次性翻转所有墙体?
    vue+element项目创建步骤
    【算法|双指针|链表】反转链表
    记一起小意外事件引起的批量重命名文件名
    大数据在智慧农业中的应用
    jstack问题定位分析
    2022年10月Web3行业月度发展报告区块链篇 | 陀螺科技会员专享
    Serverless Framework 亚马逊云(AWS)中国地区部署指南
  • 原文地址:https://blog.csdn.net/njafei/article/details/126255581