/** * https://leetcode.cn/problems/longest-substring-without-repeating-characters/?envType=study-plan-v2&envId=top-interview-150 * @param {string} s * @return {number} */ const lengthOfLongestSubstring = function (s) { }; /* 暴力解法,定义左右两个指针,左指针表示这个无重复字符串的开始位置,右指针表示无重复字符的结束位置,右指针不停的往右边遍历 每一个字符,之后再用一个循环来查找这个字符在左指针到右指针直接是否发生了重复,如果发生重复就把左指针移动到这个重复字符的 后一个位置,之后继续移动右指针 */ function f1(s) { if (s.length === 0) return 0; if (s.length === 1) return 1; let left = 0; // 定义左指针 let maxLen = 0; // 最长长度 for (let right = 1; right < s.length; right++) { // 从left到right,检查当前字符是否发生了重复 for (let i = left; i < right; i++) { if (s[i] === s[right]) { left = i + 1; break; } } maxLen = Math.max(maxLen, right - left + 1); } return maxLen; } /* 利用hash优化,我们在查找left到right直接是否有重复字符串的时,使用的是遍历,这样的化效率比较底,可以使用哈希表来储存每一个字符,值为 对应的下标,如果当前字符为哈希表中的某一个值,直接取出下标赋值给left,否则继续移动right添加新的值到哈希表中 */ function f2(s) { if (s.length === 0) return 0; let left = 0; // 定义左指针 let maxLen = 0; // 最长长度 const map = new Map(); // 用于存储字符及其最新位置 for (let right = 0; right < s.length; right++) { // 如果字符在哈希表中出现过,并且它的索引大于等于 left,说明当前窗口有重复字符 if (map.has(s[right]) && map.get(s[right]) >= left) { // 将 left 移动到重复字符的下一个位置 left = map.get(s[right]) + 1; } // 更新字符的最新位置 map.set(s[right], right); // 计算当前窗口的长度并更新最大值 maxLen = Math.max(maxLen, right - left + 1); } return maxLen; }