[LeetCode-03]无重复字符的最长子串

107 阅读1分钟

无重复字符的最长子串

刚开始的写法

比较蹩脚,只击败了5%的用户而且用时比较长 维护了两个变量,用的是数组,判断的情况还特别的多,主要的过程就是让lastI一直往前加,当i也++,使用hash来检测是否有重复出现的字段,有则记录最大length,然后lastI++,i=lastI,一直往下走。指导遍历到最后返回最大比较的长度。

var lengthOfLongestSubstring = function (s) {
  if (!s.length || s.length === 1) {
    return s.length;
  }
  let sMax = 0;
  let i = 0;
  let stack = [];
  let map = {};
  let lastI = 0;
  while (lastI < s.length) {
    if (i >= s.length) {
      lastI++;
      i = lastI;
    } else {
      if (stack.length) {
        if (!map[s[i]] && s[i]) {
          stack.push(s[i]);
        } else {
          sMax = Math.max(stack.length, sMax);
          lastI++;
          i = lastI;
          stack = [s[i]];
          map = {};
        }
      } else {
        stack.push(s[i]);
      }
    }

    map[s[i]] = 1;
    i++;
  }
  return Math.max(stack.length, sMax);
};

滑动窗口的写法

主要创建一个set,遍历字符串,检测是否存在该字段,不存在则新增到set里面,然后更新长度,存在则让l++,一直删除到没有重复为止,然后添加进set里面,直到遍历结束,返回最大长度

var lengthOfLongestSubstring = function (s) {
  let maxLength = 0;
  let l = 0;
  let set = new Set();
  if (!s.length) {
    return 0;
  }
  for (let r = 0; r < s.length; r++) {
    if (!set.has(s[r])) {
      set.add(s[r]);
      maxLength = Math.max(maxLength, set.size);
    } else {
      while(set.has(s[r])) {
        set.delete(s[l])
        l++
      }
      set.add(s[r])
    }
  }
  return maxLength
};