返回

一览众山小:破解最长不含重复字符子字符串的 JS 难关

前端

我的 JS 算法爬坑之旅——最长不含重复字符的子字符串

作为一名前端开发者,我时常穿梭于 JavaScript 的世界,探索其语言的奥秘。然而,最近我却在最长不含重复字符子字符串的算法问题上栽了跟头,深陷代码的沼泽。本篇文章将分享我在这趟爬坑之旅中的曲折经历,希望能为各位 JavaScript 爱好者提供一些借鉴。

剑指难题,初入算法世界

算法问题,如同一个个难题,考验着程序员的思维与实践能力。这次的挑战来自 LeetCode 的第 48 题,旨在求出一个字符串中最长不包含重复字符的子字符串。

刚开始,我信心满满,尝试暴力求解:遍历字符串,逐个字符添加进一个结果子串中,遇到重复字符时就清空结果子串,重新开始。然而,当字符串长度过长时,这种方法的效率低下,简直是算法中的“龟速”。

柳暗花明,巧用滑动窗口

功夫不负有心人,在深入研究问题后,我找到了算法的“捷径”——滑动窗口。滑动窗口算法的核心思想是维护一个窗口,窗口内存储着不包含重复字符的子字符串。当窗口内出现重复字符时,窗口向右移动一步,继续扩展。

趟过泥潭,优化细节

尽管滑动窗口算法效率大大提高,但仍然存在一些优化空间。我通过以下技巧进一步提升算法性能:

  • 使用哈希表记录字符上次出现的位置,避免重复查找。
  • 巧用双指针维护滑动窗口,减少不必要的比较。
  • 提前预处理字符串,去除多余字符。

峰回路转,代码精进

在优化细节之后,我的 JavaScript 算法代码焕然一新,效率得到了极大提升。以下是我精简后的代码片段:

function longestUniqueSubstring(str) {
  if (!str) return "";
  const seen = {};
  let left = 0, maxLen = 0, start = 0;
  for (let i = 0; i < str.length; i++) {
    const char = str[i];
    if (seen[char] !== undefined && seen[char] >= left) {
      left = seen[char] + 1;
    }
    if (i - left + 1 > maxLen) {
      maxLen = i - left + 1;
      start = left;
    }
    seen[char] = i;
  }
  return str.substring(start, start + maxLen);
}

后记:从算法到思考

这次的算法爬坑之旅不仅让我掌握了求解最长不含重复字符子字符串的方法,更重要的是让我理解了算法思维和优化技巧的重要性。面对算法问题,要勇于尝试,善于思考,才能突破困境,提升代码效率。愿我的分享能启迪更多的 JavaScript 爱好者,在算法的道路上披荆斩棘。