LeetCode 第三题: 无重复字符的最长子串

文章目录

  • 题目描述
  • [解题思路 - 滑动窗口法](#解题思路 - 滑动窗口法)
    • [Go语言实现 - 滑动窗口法](#Go语言实现 - 滑动窗口法)
    • 算法分析
  • [解题思路 - 优化的滑动窗口法](#解题思路 - 优化的滑动窗口法)

题目描述

给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。

示例

复制代码
输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是子串的长度,"pwke" 是一个子序列,不是子串。

解题思路 - 滑动窗口法

这个问题可以用"滑动窗口"技术来解决。滑动窗口是数组/字符串问题中常用的抽象概念。窗口通常是在数组/字符串中由开始和结束索引定义的一系列元素的集合,即 [i, j)(左闭右开)。在这里,我们将使用哈希集合来检查一个字符是否已经在当前的子串中。我们可以使用两个指针表示字符串中的某个子串(或窗口)的左右边界。右指针向右移动扩大窗口直到右指针到达字符串尽头;左指针向右移动以减小窗口直到窗口不再包含重复字符。在移动指针的过程中,我们记录并更新不含重复字符的最长子串的长度。

Go语言实现 - 滑动窗口法

go 复制代码
func lengthOfLongestSubstring(s string) int {
    charIndexMap := make(map[byte]int)
    maxLength := 0
    for i, j := 0, 0; j < len(s); j++ {
        if index, ok := charIndexMap[s[j]]; ok {
            i = max(i, index)
        }
        maxLength = max(maxLength, j-i+1)
        charIndexMap[s[j]] = j + 1
    }
    return maxLength
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

算法分析

  • 时间复杂度: O(n),其中 n 是字符串的长度。我们只需要遍历一次字符串即可。
  • 空间复杂度: O(min(m, n)),其中 m 是字符集的大小。这是因为哈希集合的大小取决于字符串中不同字符的数量,这个数量最大不会超过字符集的大小,同时也不会超过字符串的长度。

解题思路 - 优化的滑动窗口法

虽然上述滑动窗口法已经很高效,但在某些情况下,当窗口内的字符被移除时,我们可以跳过窗口中的一些字符,直接移动到重复字符的下一个位置,这可以通过存储字符的最新索引来实现。

这个方法与上面提到的滑动窗口法实际上是一样的。优化点主要在于如何更有效地更新左指针的位置。在实践中,由于这种情况出现的不多,所以实际的性能提升可能不大。因此,上面的实现已经足够满足大多数情况下的需求。

相关推荐
智者知已应修善业1 小时前
【求中位数】2024-1-23
c语言·c++·经验分享·笔记·算法
地平线开发者1 小时前
PTQ 量化数值范围与优化
算法·自动驾驶
sali-tec1 小时前
C# 基于halcon的视觉工作流-章68 深度学习-对象检测
开发语言·算法·计算机视觉·重构·c#
测试人社区-小明2 小时前
智能弹性伸缩算法在测试环境中的实践与验证
人工智能·测试工具·算法·机器学习·金融·机器人·量子计算
罗西的思考2 小时前
【Agent】MemOS 源码笔记---(5)---记忆分类
人工智能·深度学习·算法
GSDjisidi4 小时前
东京IT软件会社-(株)GSD|多种技术栈募集,高度人才+20分
开发语言·面试·职场和发展
qq_433554545 小时前
C++数位DP
c++·算法·图论
AshinGau5 小时前
Softmax 与 交叉熵损失
神经网络·算法
似水এ᭄往昔6 小时前
【C++】--AVL树的认识和实现
开发语言·数据结构·c++·算法·stl
栀秋6666 小时前
“无重复字符的最长子串”:从O(n²)哈希优化到滑动窗口封神,再到DP降维打击!
前端·javascript·算法