给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 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
查看评论