2. 无重复字符的最长子串【LC003】

146 阅读2分钟

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

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

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

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

关键思路:【滑动窗口类型】

应该是从头到尾遍历这个字符串长度, 从每个位置(cur)开始,向后找下一个值等于cur的长度。

首先,理解下思路, 以“eabcdaxxxxxx”为例, 因为我们是有从左向右的顺序,所以当遇到重复字母时(以a为例),无论前面(第二个及之前)窗口怎么滑动,最大长度只可能出现在下面位置之间: 1)至第二个a之前一位,这个会暂时将最大长度标识为第二个a之前一位; 2)第二个a之后,将start位置调整到第一个a之后一位;

怎么解释这个呢,以上述字符串为例,可以理解在出现第二个a之前的最大滑窗是eabcd, 所以无论第二个a之后的字符是什么,前面的最大滑窗已经确定,都将重新开始重新计算滑窗。所以将从第一个a之后一位重新开始计算滑窗,当前划窗长度会有所缩短,变成bcda。是不是就清晰了。

image.png

function getMaxDiffStrLen(str) {
  if (!str) {
    return 0;
  }
  let len = str.length;
  let maxLen = 0;
  //  维护划窗
  let queue = [];
  let left = 0;// start指针
  let curLen = 0;
  
  for (let i = 0; i < len; i++) {
    let item = str[i];
    curLen += 1;

    while (queue.includes(item)) {
      queue.shift();
      curLen -= 1;
      left += 1;
    }
    if (curLen > maxLen) {
      maxLen = curLen;
    }
    queue.push(item)
  }
  return maxLen;
}

———— 前端、Javascript实现、算法、刷题、leetcode