You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript无重复最长子串函数:滑动窗口管理问题咨询

无重复字符最长子串问题解惑

先给出修正后的正确实现代码:

function subs(s) {
    const set = new Set();
    let left = 0;
    let total = 0;
    for(let right = 0; right < s.length; right++) {
        // 用while循环移除所有导致重复的左边界元素
        while(set.has(s[right])){
            set.delete(s[left]);
            left++;
        }
        set.add(s[right]);
        total = Math.max(total, right - left + 1);
    }
    return total;
}

问题1:为什么while循环能解决重复检测问题?

你的初始代码用if语句,只会在发现重复时移除一次左边界元素,但这无法保证窗口内完全消除与s[right]的重复。举个实际例子:

  • 输入字符串"abba",当right遍历到最后一个a(索引3)时,此时set中是{'a','b'},s[right]为'a'。
  • 用if的话,只会删除s[left](即'a'),left变为1,但set里还剩'b',接下来执行set.add('a'),此时窗口是[1,3](对应字符'b','b','a'),明显包含重复的'b',但set里变成{'b','a'},计算长度时会得到错误的结果3。

而while循环会持续移动左指针并移除对应元素,直到set中不再包含s[right]。还是上面的例子:

  • 当right=3时,set.has('a')为true,进入循环:删除s[0]('a'),left=1;此时set里是{'b'},set.has('a')为false,退出循环。
  • 再执行set.add('a'),窗口是[1,3](对应字符'b','a'),无重复,长度计算正确。

本质区别:if只能处理重复元素恰好是当前左边界的情况,而while能处理重复元素在窗口任意位置的情况,确保滑动窗口始终满足「无重复字符」的核心条件。

问题2:指针操作与元素删除的正确顺序是什么?

正确顺序是:先删除当前left指向的元素,再递增left指针。

如果反过来先执行left++再删除,会导致你删除的是left递增后的位置对应的元素,而原来的左边界元素还留在set中,破坏了set与滑动窗口的一致性。举个例子:

  • 假设当前left=0,set里包含s[0],此时检测到重复,若先left++(变成1),再set.delete(s[left])(即删除s[1]),那么s[0]还留在set里,但滑动窗口已经从1开始了,set里的元素和窗口实际包含的元素不匹配,后续的重复检测必然出错。

正确逻辑是:滑动窗口的左边界是left,要把这个元素移出窗口,就得先从set里删掉它,再把left往右移,这样set才能始终准确反映窗口内的所有元素。

内容的提问来源于stack exchange,提问作者Sanjay sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 07:45:04