前端js算法题之LCR 016. 无重复字符的最长子串

115 阅读2分钟

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

image.png

方案一: 解题思路:首先想到需要循环遍历,将每一次遍历元素放入新的数组中,先看有无重复元素,有,通过 indexOf 找到重复元素在字符串中位置索引(hasItemIndex),然后删除从 0 开始到重复索引(hasItemIndex)之间字符;没有,将遍历的元素插入到新的数组中;每一次判断新数组的长度,取最大值。

/**
 * @param {string} s
 * @return {number}
 */
const lengthOfLongestSubstring = function(s) {
  if (s.length === 1) return 1; 
  let arr = [], max = 0;
  for (let index = 0; index < s.length; index++) {
      // 找到这个字符在数组中的索引
    let hasItemIndex = arr.indexOf(s[index]);
    if (hasItemIndex !== -1) {
        // 删除从0到这个重复字符的长度
      arr.splice(0,hasItemIndex+1)
    }
    arr.push(s.charAt(index));
    max = Math.max(max, arr.length);
  }
  return max
};

方案二: 解题思路:创建一个 Map 对象,存储已经遍历的数组,将遍历的元素作为key ,元素对应的索引作为 value 。变量 i 存放无重复字串的位置 ,j 存放元素遍历的索引。遍历字符串,判断当前字符串是否存在 map 对象中,如果存在,找到存在元素的下标并更新无重复字串下标为相同字符的下一个位置,此时,从 i 到 j 就是最新的无重复字串,更新最大长度max,并将当前元素放入 map 中。返回 max 。

const lengthOfLongestSubstring = function(s) {
  if(s.length === 1) return 1;
  let map = new Map(), max= 0 ;
  // i记录无重复字串字串的下标,j是遍历字符索引
  for (let i = 0, j = 0; j < s.length; j++) {
    if(map.has(s[j])){
      // 有重复元素时,更新无重复字串下标为重复元素下标的下一个位置,
      //(无重复字串下标和当前重复下标的最大值)
      i = Math.max(map.get(s[j])+1, i)
    }
    map.set(s[j],j); // key -> 元素, value -> 元素对应的索引
    max = Math.max(j-i+1, max)
  }
  return max  
};