LeetCode 392 判断子序列


文章目录

摘要

在字符串的日常处理场景里,判断一个字符串是不是另一个字符串的子序列是非常常见的需求。比如在搜索推荐里,我们输入一个简写,系统要判断这个简写是不是某个候选词的子序列,从而决定是否推荐。LeetCode 392 就是这样一道题:给定两个字符串 st,判断 s 是否为 t 的子序列。

本文会从题目分析、解题思路、Swift 实现代码到示例测试,带大家完整拆解这道题,并结合进阶问题聊聊在大规模数据场景下的优化思路。

描述

题目的要求很直白:

  • 子序列的定义是 删除原字符串的部分字符,但保留剩余字符的相对顺序
  • 比如 "abc""ahbgdc" 的子序列,因为我们可以依次找到 'a' -> 'b' -> 'c',而不用考虑中间的 'h', 'g', 'd'
  • "axc" 就不是 "ahbgdc" 的子序列,因为虽然有 'a',但找不到 'x'

换句话说,这就是一个 顺序匹配问题

题解答案

解决思路其实非常直接:

  1. 用两个指针,一个扫描 s,一个扫描 t
  2. 如果两个指针指向的字符相同,就让 s 的指针前进;不管相不相同,t 的指针总是往前。
  3. 如果 s 的指针走到了末尾,就说明 st 的子序列。

这种方法特别高效,时间复杂度线性,非常适合这类顺序匹配问题。

题解代码分析

下面是 Swift 的实现代码:

swift 复制代码
import Foundation

class SubsequenceChecker {
    func isSubsequence(_ s: String, _ t: String) -> Bool {
        // 转成数组方便按下标访问
        let sChars = Array(s)
        let tChars = Array(t)
        
        var i = 0, j = 0
        while i < sChars.count && j < tChars.count {
            if sChars[i] == tChars[j] {
                i += 1 // 匹配成功,移动 s 指针
            }
            j += 1 // 不管怎样,t 指针都要前进
        }
        return i == sChars.count
    }
}

代码解析

  1. 字符串转数组

    在 Swift 中字符串不是直接按下标可访问的,所以需要转成字符数组,方便用下标访问。

  2. 双指针

    • i 指向 sj 指向 t
    • 如果当前字符相同,就把 i 向前推进。
    • j 每次都要前进,保证扫描完整个 t
  3. 终止条件

    • 如果 i 成功走到 s 的末尾,说明所有字符都匹配了。
    • 如果 t 扫描完了,但 i 还没走到末尾,那就说明匹配失败。

示例测试及结果

swift 复制代码
let checker = SubsequenceChecker()

print(checker.isSubsequence("abc", "ahbgdc"))
// 输出: true
// 因为可以在 "ahbgdc" 里依次找到 a -> b -> c

print(checker.isSubsequence("axc", "ahbgdc"))
// 输出: false
// 因为 "ahbgdc" 里没有 x

print(checker.isSubsequence("", "ahbgdc"))
// 输出: true
// 空串永远是任何字符串的子序列

时间复杂度

在最坏情况下,我们需要扫描完整个 t

  • 时间复杂度是 O(n) ,其中 n 是字符串 t 的长度。

空间复杂度

除了把字符串转成数组,我们没有额外使用额外的存储。

  • 空间复杂度是 O(1)(如果忽略输入转数组的开销)。

总结

这道题的核心思路是 双指针顺序匹配,思路清晰,代码也简洁。它不仅在刷题里有用,实际场景中也很常见:

  • 比如在模糊搜索时,判断关键字是否是候选词的子序列;
  • 在命令行工具里,检查简写命令是否可以映射到完整命令;
  • 在推荐系统里,输入简短的前缀时,判断是否能匹配到目标词。

如果进一步考虑 进阶问题 (大量 s 要判断是否为 t 的子序列),那就需要对 t 做一次预处理,比如构建一个 字符到下标的映射表,用二分搜索加速匹配,这样查询的效率会更高。

相关推荐
艾莉丝努力练剑7 分钟前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
偷吃的耗子38 分钟前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
dazzle1 小时前
机器学习算法原理与实践-入门(三):使用数学方法实现KNN
人工智能·算法·机器学习
那个村的李富贵2 小时前
智能炼金术:CANN加速的新材料AI设计系统
人工智能·算法·aigc·cann
张张努力变强2 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
万岳科技系统开发2 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
张登杰踩2 小时前
MCR ALS 多元曲线分辨算法详解
算法
YuTaoShao2 小时前
【LeetCode 每日一题】3634. 使数组平衡的最少移除数目——(解法一)排序+滑动窗口
算法·leetcode·排序算法
波波0072 小时前
每日一题:.NET 的 GC是如何分代工作的?
算法·.net·gc
HY小宝F2 小时前
职场沟通的深层智慧:从对抗到协作的自我修炼
职场和发展