返回

手把手教你三种解法,轻松拿捏 LeetCode 无重复字符的最长子串!

前端

前言

在 LeetCode 的浩瀚题海中,“无重复字符的最长子串”可谓经典之作。它不仅考察了你的字符串处理能力,也考验了算法设计方面的功力。本篇文章将为你揭开这道题目的神秘面纱,并手把手教你三种 JavaScript 解法。

三种解法

1. Set + 滑动窗口

使用 Set 来存储滑动窗口中的字符,确保不重复。滑动窗口的左边界收缩直到窗口中没有重复字符为止。

const lengthOfLongestSubstring = (s) => {
  const set = new Set();
  let left = 0, maxLen = 0;

  for (let right = 0; right < s.length; right++) {
    if (set.has(s[right])) {
      while (set.has(s[right])) {
        set.delete(s[left]);
        left++;
      }
    }
    set.add(s[right]);
    maxLen = Math.max(maxLen, right - left + 1);
  }

  return maxLen;
};

2. 滑动窗口 + 收缩窗口

类似于第一种解法,但使用一个固定大小的窗口,不断收缩直到窗口中没有重复字符为止。

const lengthOfLongestSubstring = (s) => {
  if (!s) return 0;
  let [left, right, maxLength] = [0, 0, 0];
  const charMap = {};

  while (right < s.length) {
    if (charMap[s[right]] === undefined) {
      charMap[s[right]] = 1;
      maxLength = Math.max(maxLength, right - left + 1);
      right++;
    } else {
      while (charMap[s[right]] !== undefined) {
        charMap[s[left]]--;
        if (charMap[s[left]] === 0) delete charMap[s[left]];
        left++;
      }
      charMap[s[right]] = 1;
      right++;
    }
  }

  return maxLength;
};

3. 直白通俗解法

直接使用双指针遍历字符串,计算滑动窗口的长度。当发现重复字符时,将左指针移动到重复字符的下一位。

const lengthOfLongestSubstring = (s) => {
  let maxLength = 0;
  let left = 0;
  let charMap = {};

  for (let right = 0; right < s.length; right++) {
    if (charMap[s[right]] !== undefined) {
      left = Math.max(left, charMap[s[right]] + 1);
    }
    charMap[s[right]] = right;
    maxLength = Math.max(maxLength, right - left + 1);
  }

  return maxLength;
};

总结

通过这三种 JavaScript 解法,我们深入理解了滑动窗口和收缩窗口技术在字符串处理中的应用。希望这些解析能帮助你加深对算法设计和字符串处理的理解。此外,我们也提供了详细的代码注释,方便你深入剖析算法的实现细节。