代码训练LeetCode(36)判断子序列

代码训练(36)判断子序列

Author: Once Day Date: 2025年6月17日

漫漫长路,才刚刚开始…

全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客

参考文章:

1. 原题

给定字符串 st ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace""abcde"的一个子序列,而"aec"不是)。

**进阶:**如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

示例 1:

输入:s = "abc", t = "ahbgdc"
输出:true

示例 2:

输入:s = "axc", t = "ahbgdc"
输出:false
2. 分析

本题要求判断一个字符串 s 是否是另一个字符串 t 的子序列。子序列的定义是在不改变字符顺序的情况下,可以通过删除一些字符(或不删除)从 t 中得到 s。

基本方法:双指针法: 使用两个指针,一个指向 s,一个指向 t。同时遍历 s 和 t,如果字符匹配,则两个指针都向前移动;如果不匹配,只移动指向 t 的指针。如果能在 t 的末尾之前或同时遍历完 s,则 s 是 t 的子序列。

进阶方法:针对大量输入的 S1, S2, …, Sk 检查是否为 T 的子序列,可以使用以下方法优化:

  1. 预处理 T:创建一个映射,记录 t 中每个字符出现的所有位置。
  2. 二分查找:对于每个输入的 s,使用二分查找快速定位每个字符在 t 中的位置,确保它们的顺序符合子序列的要求。

分析步骤:

  1. 初始化: 创建两个指针,分别指向 s 和 t 的起始位置。
  2. 遍历比较: 同时遍历 s 和 t,根据字符是否匹配移动指针。
  3. 检查结果: 查看 s 的指针是否已经遍历完整个字符串,如果是,则 s 为 t 的子序列。

举例分析,假设 s = “abc”, t = “ahbgdc”:

  • 初始化两个指针分别指向 s 和 t 的起始位置。
  • 比较 s[0] 和 t[0] => ‘a’ == ‘a’,两个指针都前进。
  • 比较 s[1] 和 t[1] => ‘b’ != ‘h’,只移动指向 t 的指针。
  • 比较 s[1] 和 t[2] => ‘b’ == ‘b’,两个指针都前进。
  • 比较 s[2] 和 t[3] => ‘c’ != ‘g’,只移动指向 t 的指针。
  • 比较 s[2] 和 t[4] => ‘c’ != ‘d’,只移动指向 t 的指针。
  • 比较 s[2] 和 t[5] => ‘c’ == ‘c’,两个指针都前进。
  • 所有字符匹配完成,s 是 t 的子序列。

性能优化关键点:

  • 减少不必要的比较: 使用双指针法避免对整个字符串的全面扫描。
  • 减少重复检查: 对于进阶问题,通过预处理和二分查找减少重复的位置检查。
3. 代码实现
#include <stdbool.h>
#include <string.h>

bool isSubsequence(char *s, char *t) {
    int indexS = 0, indexT = 0;
    int lenS = strlen(s), lenT = strlen(t);
    
    while (indexS < lenS && indexT < lenT) {
        if (s[indexS] == t[indexT]) {
            indexS++;
        }
        indexT++;
    }
    
    return indexS == lenS;
}
4. 总结

本题考察了字符串操作和双指针技巧,对于基础的子序列检查问题,使用双指针法已足够高效。对于进阶问题,通过合理的数据结构和算法优化,如预处理和二分查找,可以有效应对大规模数据的挑战。通过这类问题,可以加强对字符串处理和算法优化的理解和应用,有助于提高编程能力和解决实际问题的能力。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值