小言_互联网的博客

LeetCode-算法题系列 (十六) => 无重复字符的最长子串

316人阅读  评论(0)

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

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

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

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

解法一(常规思路)

思路

  • 一、从头添加数组,遇到重复的就打断循环->从第二位进行比较,记录数组长度
  • 二、重复之前的动作,比较当前数组长度与上一次数组长度
  • 三、考虑边界,每次 下标++,数组长度–
  • 判断过程就是一个可以滑动和伸缩的格子,他套住一个又一个满足条件的值,最后返回了各自的长度
var lengthOfLongestSubstring = function(s) {
    var arr = s.split('')
    var nums = [],len = arr.length,resMax = 0,index = 0
    while(index < len){
        var max = 0
        for(let i = 0; i < arr.length; i++){
            if(nums.indexOf(arr[i]) == -1){
                nums.push(arr[i])
                max = nums.length > max ? nums.length : max
            }else{
                nums = []
                break
            }
        }
        resMax = max > resMax ? max : resMax 
        arr.shift()
        index++
    }
    return resMax
};

此思路虽然还有优化的空间(比如,条件判断缩减为 index < len - resMax、arr.slice(indexOf(arr[i])) 等等),但是超高的时间和空间占用率都表明它是不推荐的说来惭愧,想出来的结果离最优解还是有差距)但是这种思路却是正确的,我们将它抽离出来并形成解法二

解法二(滑动窗口)

思路

  • 一、从0开始判断新字符串是否存在当前值(有一点类似去重的前半部分)
  • 二、随时更新字符串长度,用于得到max值
  • 三、如果发现了重复项我们虽然会继续添加,但是我们从相同值首次出现的位置截取之后一位截取。
var lengthOfLongestSubstring = function(s) {
    let len = 0;
    let val = '';
    for (let i = 0; i < s.length; i++) {
        if (val.indexOf(s[i]) === -1) {
            val = val + s[i];
            if (val.length > len) {
                len = val.length;
            }
        } else {
            val = val + s[i];
            let index = val.indexOf(s[i]);
            val = val.slice(index + 1);
        }
    }
    return len;
};


转载:https://blog.csdn.net/jbj6568839z/article/details/102544600
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场