当前位置: 首页 > news >正文

LeetCode算法题(Go语言实现)_11

题目

给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

一、代码实现

基础解法(双指针法)
func isSubsequence(s string, t string) bool {
    i, j := 0, 0
    for i < len(s) && j < len(t) {
        if s[i] == t[j] {
            i++
        }
        j++
    }
    return i == len(s)
}
进阶解法(预处理+二分搜索)
func isSubsequenceAdvanced(s string, t string) bool {
    // 预处理:记录每个字符在t中的位置
    index := make(map[byte][]int)
    for i := 0; i < len(t); i++ {
        c := t[i]
        index[c] = append(index[c], i)
    }

    // 匹配s的每个字符
    currentPos := 0
    for i := 0; i < len(s); i++ {
        c := s[i]
        positions, exists := index[c]
        if !exists {
            return false
        }
        // 二分查找第一个>=currentPos的位置
        pos := sort.SearchInts(positions, currentPos)
        if pos == len(positions) {
            return false
        }
        currentPos = positions[pos] + 1
    }
    return true
}

二、算法分析

1. 核心思路
  • 双指针法:通过两个指针同步遍历 st,匹配字符后移动 s 指针,最终判断 s 是否遍历完成。
  • 预处理优化:针对大量 s 输入的情况,预处理 t 的结构(记录每个字符的索引位置),使用二分查找快速定位匹配位置,减少重复遍历 t 的时间。
2. 关键步骤
  1. 双指针法

    • 初始化 i(指向 s)和 j(指向 t)为0。
    • 每次匹配成功时 ij 同时右移,否则仅 j 右移。
    • i 遍历完 s 时返回 true
  2. 预处理优化

    • 构建哈希表,记录 t 中每个字符的所有出现位置。
    • 对每个 s 的字符,在其对应的位置列表中二分查找第一个不小于当前匹配位置的值。
3. 复杂度
方法时间复杂度空间复杂度适用场景
双指针法O(n)(n为t长度)O(1)单次查询
预处理+二分查找O(mlogk)O(n)大量查询(k≥10亿次)

三、图解

在这里插入图片描述

四、边界条件与扩展

1. 边界条件
  • s为空:空字符串是任何字符串的子序列。
  • t为空:若s非空则返回false
  • s比t长:直接返回false
2. 扩展验证
  • 大规模数据:预处理方法可在O(1)时间内完成单次查询(预处理时间O(n))。
  • 特殊字符:算法天然支持所有ASCII字符(需扩展哈希表范围)。
3. 算法对比
方法优势劣势
双指针法代码简单,空间O(1)无法应对大量查询
动态规划可复用LCS逻辑时间O(mn),空间O(mn)
预处理+二分查找处理10亿级查询时效率高预处理时间O(n)

五、总结

  • 核心逻辑:双指针法通过同步遍历快速判断子序列关系,时间复杂度为O(n);预处理方法通过空间换时间优化高频查询场景。
  • 优化点
    1. 双指针法的贪心策略确保匹配位置的最左对齐,避免回溯。
    2. 预处理方法利用哈希表+二分查找将单次查询复杂度降为O(mlogk)。
  • 应用场景:实时数据流中的子序列匹配(如日志分析)、高频查询系统设计(如API服务)。

相关文章:

  • (每日一道算法题) K 个一组翻转链表
  • 2025宠物智能喂养设备全栈开发方案:Python驱动的高效实现路径
  • IntelliJ IDEA创建Maven工程
  • Ardupilot开源无人机之Geek SDK进展2025Q2
  • 我的世界1.20.1forge模组进阶开发教程——结构(3)
  • 华为 eNSP 链路聚合:从面试问题到实战解析
  • MySQL数据库精研之旅第四期:解锁库操作高阶技能
  • Python数据可视化与数据处理全解析:Matplotlib图形控制与Pandas高效数据分析实战
  • MySQL中的Redo Log、Undo Log和Binary Log
  • 大模型在支气管肺癌预测及临床决策中的应用研究报告
  • 蓝桥杯 临时抱佛脚 之 二分答案法与相关题目
  • 【设计模式】抽象工厂模式(含与工厂方法模式的对比)
  • Unity-RectTransform设置UI width
  • wokwi arduino mega 2560 - 模数与数模转换AD和DA
  • 设置git拉取的文件换行格式
  • Codeforces Round 1013 (Div. 3)
  • 企业入驻成都国际数字影像产业园,可享150多项专业服务
  • AwesomeQt分享(含源码)
  • Leetcode 路径总和 III
  • 振弦采集读数仪 智能型 支持振弦、温度、电压、电流测量,无线传输 自动化操作 适用地质灾害与土木工程监测
  • 第四轮伊美核谈判将于11日在阿曼举行
  • 夜读丨喜马拉雅山的背夫
  • 图忆|红场阅兵:俄罗斯30年来的卫国战争胜利日阅兵式
  • 新华时评:直播间里“家人”成“韭菜”,得好好管!
  • 洞天寻隐·学林纪丨玉洞桃源:仇英青绿山水画中的洞天与身体
  • 司法部:建立行政执法监督企业联系点,推行行政执法监督员制度