【温故知新】js经典编程‘无重复字符的最长子串长度’

232 阅读2分钟

题目

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

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/lo…

解题思路1: 通过array;

  • 通过arr来存储当前无重复子串的元素;

  • 通过max来计算当前遍历下,最大的无重复子串的长度;

  • 通过arr.indexOf(item);来判断当前数组中是否存在当前遍历元素;

  • 如果存在,则通过arr.splice(index,howmany);来删除相同元素及之前的所有元素;

  • 压入当前遍历元素,arr.push(s.charAt(i));此时arr为最新的无重复子串,

  • 通过Math.max();得出当前遍历下的无重复子串的最大长度;

  • 返回最大值max;

      /**
       * @param {string} 
       * @return {number}
       */
      var lengthOfLongestSubstring = function(s) {
       let max=0,arr=[],len=s.length;
          for(let i=0;i<len;i++){
              index=arr.indexOf(s[i]);
              if(index!==-1){
                arr.splice(0,index+1);
              }
              arr.push(s.charAt(i));
              max=Math.max(arr.length,max);
          }
          return max;
      };
    

116 ms 39.3 MB

解题思路2:通过map

  • 使用map()来存储当前遍历的val值和下标key值;map.set(val,key);

  • 通过for loop 遍历一遍字符串数组,使用i来标记当前无重复子串的起始坐标;通过j来标记当前遍历的下标;

  • 通过map.has(val);来判断当前map中是否存在当前遍历元素,存在则更新坐标i;

  • 通过max来统计当前已经遍历过的无重复子串的最大长度;

  • 通过Math.max(j-i+1,max);数学函数来计算当前max的最大值;

  • 返回最大值max;

      /**
       * 
       * @param {string} 
       * 
       * @return {number}
       * 
       * 
       */
      var lengthOfLongestSubstring = function(s) {
          let map=new Map(),len=s.length,max=0;
          for(let i=0,j=0;j<len;j++){
              if(map.has(s[j])){
                  // 移动最新的无重复开始下标i;
                  i=Math.max(map.get(s[j])+1,i);
              }
                 
                  map.set(s[j],j);
                 // j-i+1 为当前遍历中最新的无重复子串的长度;只关心最近的i;
                  max=Math.max(max,j-i+1);
          }
          return max;
      };
    

124 ms 38.7 MB

时间复杂度:O(n)

空间复杂度:O(n)