从字符串中“薅出”最长子串:LeetCode 340 Swift 解法全解析


文章目录

摘要

在日常开发中,我们经常需要处理字符串,比如分析用户输入、文本挖掘、数据清洗等等。而这道题就特别实用:如何找到一个字符串中最多包含 K 个不同字符的最长子串?本篇文章将用 Swift 手把手带你搞懂滑动窗口的使用技巧,从思路到代码再到复杂度分析,一站式搞定。

描述

题目是这样描述的:

给定一个字符串 s 和一个整数 k,请你找出字符串中 最多包含 k 个不同字符的最长子串的长度

这个问题的关键在于"最多包含 K 个不同字符",也就是说超过 K 个不同字符就不符合要求,我们要把这个限制"滑动"管理好。

题解答案

我们使用 滑动窗口 + 哈希表 的经典组合来解决这个问题。滑动窗口主要用来维护当前的子串区间,而哈希表负责统计窗口内字符的出现频次。

核心思路:

  • 用两个指针维护一个窗口 [left, right]
  • 用一个 Dictionary<Character, Int> 来记录当前窗口内每个字符的出现次数
  • 如果窗口里的不同字符数超过 K,就不断左移窗口直到满足条件
  • 在每次满足条件的窗口中更新最大长度

题解代码分析

swift 复制代码
func lengthOfLongestSubstringKDistinct(_ s: String, _ k: Int) -> Int {
    if k == 0 || s.isEmpty { return 0 }

    let chars = Array(s)
    var left = 0
    var maxLength = 0
    var charCount = [Character: Int]()

    for right in 0..<chars.count {
        let rightChar = chars[right]
        charCount[rightChar, default: 0] += 1

        // 当不同字符数量超过 k,移动左指针收缩窗口
        while charCount.keys.count > k {
            let leftChar = chars[left]
            charCount[leftChar]! -= 1
            if charCount[leftChar]! == 0 {
                charCount.removeValue(forKey: leftChar)
            }
            left += 1
        }

        // 记录当前符合条件的最大长度
        maxLength = max(maxLength, right - left + 1)
    }

    return maxLength
}

详细解析:

  • charCount[rightChar, default: 0] += 1:把新字符加入窗口并计数
  • charCount.keys.count > k:检查窗口是否超出 K 种字符
  • charCount.removeValue(forKey: leftChar):清理掉数量为 0 的字符,保持哈希表干净
  • right - left + 1 是当前窗口长度,每次都尝试更新最大值

示例测试及结果

swift 复制代码
print(lengthOfLongestSubstringKDistinct("eceba", 2)) // 输出 3,子串为 "ece"
print(lengthOfLongestSubstringKDistinct("aa", 1))    // 输出 2,子串为 "aa"
print(lengthOfLongestSubstringKDistinct("abcadcacacaca", 3)) // 输出 11,子串为 "cadcacacaca"

结果解释:

  • 示例 1:子串 "ece" 有两个不同字符,长度为 3
  • 示例 2:整个字符串只有一种字符,直接返回长度 2
  • 示例 3:可以从第 2 个字符开始算起,取到最长满足条件的子串 "cadcacacaca"

时间复杂度

  • 时间复杂度:O(n)
    整个字符串遍历一遍,每个字符最多进出窗口一次。
  • 空间复杂度:O(k)
    哈希表最多存储 K 个不同字符的频率。

总结

这道题是滑动窗口思想的经典应用,通过"收缩窗口"控制不同字符的种类,再通过变量记录最长长度。在实际项目里,如果你在做关键词搜索优化、用户行为分析、或者简单的文本压缩策略,这类"限定种类数量"的需求其实挺常见的。

Swift 写法也很清晰,用 Dictionary 来统计频次,逻辑直观,性能也不错。

相关推荐
江畔柳前堤1 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore2 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考4 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX4 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面5 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号5 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽5 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI5 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者7 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者7 小时前
【征程6】校准量化中HistogramObserver解析
算法