返回

前端面试每日 3+1,打通算法与数据结构的任督二脉!

前端

前端面试每日 3+1:破解无重复字符的最长子字符串难题

简介

前端面试是前端工程师求职中的关键环节,而掌握面试题的解法至关重要。本系列文章“前端面试每日 3+1”旨在帮助前端工程师深入理解面试题,提升面试表现。

今天,我们将共同攻克一道经典面试题:找出给定字符串中不含有重复字符的最长子字符串的长度。

滑动窗口算法

解决这道题的关键在于滑动窗口算法。该算法通过一个在字符串中滑动的窗口,快速高效地寻找满足特定条件的子字符串。

在滑动窗口算法中,我们使用一个数据结构(如哈希表)来记录窗口中出现的字符。当窗口滑动时,我们可以根据数据结构中的信息判断窗口中的子字符串是否满足条件。

代码实现

以下是使用滑动窗口算法解决此题的 JavaScript 代码:

function lengthOfLongestSubstring(s) {
  if (!s || s.length === 0) return 0;

  let maxLen = 0, left = 0, right = 0;
  const charMap = new Map();

  while (right < s.length) {
    const char = s[right];
    if (charMap.has(char)) {
      left = Math.max(left, charMap.get(char) + 1);
    }
    charMap.set(char, right);
    maxLen = Math.max(maxLen, right - left + 1);
    right++;
  }

  return maxLen;
}

示例与解释

以下示例演示了算法的运行过程:

输入: s = "abcabcbb"

步骤:

  1. 窗口 [a]

    • charMap: { a: 0 }
  2. 窗口 [ab]

    • charMap: { a: 0, b: 1 }
  3. 窗口 [abc]

    • charMap: { a: 0, b: 1, c: 2 }
  4. 窗口 [abca]

    • charMap: { a: 0, b: 1, c: 2 }
    • 发现重复字符 "a",窗口缩小至 [bca]
  5. 窗口 [bca]

    • charMap: { b: 1, c: 2, a: 3 }
  6. 窗口 [bcab]

    • charMap: { b: 1, c: 2, a: 3, b: 4 }
    • 发现重复字符 "b",窗口缩小至 [cab]
  7. 窗口 [cab]

    • charMap: { c: 2, a: 3, b: 4 }
  8. 窗口 [caba]

    • charMap: { c: 2, a: 3, b: 4, a: 5 }
    • 发现重复字符 "a",窗口缩小至 [ba]
  9. 窗口 [ba]

    • charMap: { b: 4, a: 5 }
  10. 窗口 [bab]

  • charMap: { b: 4, a: 5, b: 6 }
  • 发现重复字符 "b",窗口缩小至 [ab]
  1. 窗口 [ab]
  • charMap: { a: 5, b: 6 }

输出: 无重复字符的最长子字符串长度为 3 ("abc")

总结

通过滑动窗口算法,我们可以高效地找出字符串中不含有重复字符的最长子字符串的长度。掌握这一算法,将极大地提升你在前端面试中的表现。

常见问题解答

  1. 为什么使用哈希表来存储字符?
    哈希表可以快速查找和更新键值对,非常适合在滑动窗口算法中记录窗口中出现的字符。

  2. 滑动窗口算法的复杂度是多少?
    滑动窗口算法的时间复杂度为 O(n),其中 n 是字符串的长度。

  3. 如何处理包含空格和标点符号的字符串?
    可以根据特定需求对字符串进行预处理,例如忽略空格和标点符号。

  4. 除了滑动窗口算法外,还有其他解决方法吗?
    还有一种方法是使用暴力枚举,但效率较低。

  5. 如何优化滑动窗口算法?
    可以通过使用滚动哈希等技术进一步优化滑动窗口算法。