【算法】无重复字符的最长子串

难度:中等

题目

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

示例:

示例1:

输入:s = "abcabcbb"

输出:3

解释:因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例2:

输入:s = "pwwkew"

输出:3

解释:因为无重复字符的最长子串是 "wke",所以其长度为 3。

请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成

解题思路:

这道题目的核心在于使用滑动窗口的思想来遍历字符串,寻找不含重复字符的最长子串。滑动窗口是一种处理数组/字符串区间问题的有效方法,它可以在遍历过程中动态调整待考察的子序列(窗口)。

  1. 初始化:定义两个指针left和right,分别表示当前窗口的左右边界,初始时都指向字符串的起始位置。同时,用一个哈希表(在JavaScript中可以使用对象或Map)来记录窗口内每个字符出现的最新位置,以方便快速判断字符是否重复。
  2. 扩大窗口:将右指针right逐步向右移动,每次移动都将right指向的字符加入哈希表,并更新该字符的最新位置。如果加入字符后没有造成重复(即新加入的字符的最新位置大于等于left),则说明窗口内的字符都是唯一的,此时可以更新最长子串长度。
  3. 缩小窗口:当加入字符导致重复时,就需要移动左指针left来缩小窗口,直到窗口内的字符再次变得唯一。在移动left的过程中,需要从哈希表中删除left指向的字符,因为这个字符已经不再属于窗口。
  4. 循环进行:重复步骤2和3,直到右指针达到字符串末尾。
  5. 返回结果:循环结束后,最长子串的长度即为所求。
javascript 复制代码
/**
 * @param {string} s
 * @return {number}
 */

var lengthOfLongestSubstring = function (s) {
    let left = 0;
    let maxLength = 0;
    let charMap = new Map(); // 用于记录字符及其在字符串中的位置

    for (let right = 0; right < s.length; right++) {
        let currentChar = s[right];

        // 如果当前字符已经在窗口中存在,则需要更新左边界
        if (charMap.has(currentChar)) {
            left = Math.max(charMap.get(currentChar) + 1, left);
        }

        // 更新字符的最新位置
        charMap.set(currentChar, right);

        // 计算当前窗口的长度
        maxLength = Math.max(maxLength, right - left + 1);
    }

    return maxLength;
};

这段代码实现了上述的滑动窗口算法,通过不断调整窗口大小来寻找最长的无重复字符子串,并最终返回该子串的长度。

相关推荐
盼海7 分钟前
排序算法(四)--快速排序
数据结构·算法·排序算法
一直学习永不止步22 分钟前
LeetCode题练习与总结:最长回文串--409
java·数据结构·算法·leetcode·字符串·贪心·哈希表
Rstln1 小时前
【DP】个人练习-Leetcode-2019. The Score of Students Solving Math Expression
算法·leetcode·职场和发展
芜湖_1 小时前
【山大909算法题】2014-T1
算法·c·单链表
珹洺1 小时前
C语言数据结构——详细讲解 双链表
c语言·开发语言·网络·数据结构·c++·算法·leetcode
几窗花鸢2 小时前
力扣面试经典 150(下)
数据结构·c++·算法·leetcode
.Cnn2 小时前
用邻接矩阵实现图的深度优先遍历
c语言·数据结构·算法·深度优先·图论
2401_858286112 小时前
101.【C语言】数据结构之二叉树的堆实现(顺序结构) 下
c语言·开发语言·数据结构·算法·
Beau_Will2 小时前
数据结构-树状数组专题(1)
数据结构·c++·算法
迷迭所归处2 小时前
动态规划 —— 子数组系列-单词拆分
算法·动态规划