- 题目来源: https://leetcode.com/problems/longest-substring-without-repeating-characters/description/
- 题目: Longest Substring Without Repeating Characters
- 题目描述:
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
这一题虽然在leetCode上面的难度是Medium,但是具体一分析还相对来说算是比较没那么难的,我的思路上来就是穷举,而且跟其他人的还不太一样,我是先将所有不连续的子字符串都放进一个数组中之后,然后用sort方法进行排序,获取最大的长度并返回。上代码:
var lengthOfLongestSubstring = function(s) {
if(s.length === 0) return '';
var o = []; // {length: number, arr: []}
for(var i = 0; i < s.length; i++) {
var arr = [];
arr.push(s.charAt(i));
var j = i + 1;
while(j < s.length) {
if(arr.indexOf(s.charAt(j)) === -1) {
arr.push(s.charAt(j));
} else {
break;
}
j++;
}
o[i] = {length: arr.length, arr: arr};
}
o = o.sort(function(a, b) {
return b.length - a.length;
})
return o[0].length;
};
按照算法复杂度来说我这个已经达到了 O(n2) O ( n 2 ) ,所以在性能上面来看,这种做法真的是挺糟糕的额。看了一下别人的答案,可以找到很多复杂度为 O(n) O ( n ) 的写法,这里贴出一段只用九行代码实现的代码:
function lengthOfLongestSubstring(s) {
const map = {};
var left = 0;
return s.split('').reduce((max, v, i) => {
left = map[v] >= left ? map[v] + 1 : left;
map[v] = i;
return Math.max(max, i - left + 1);
}, 0);
}
刚刚看到这个答案的时候,花了三个小时都没有想通,后来去健身的时候就想通了。我来理一下思路,map对象存放的是字符串里面每一个字符上一次所在的位置,left是上一次上一个重复字符出现的位置,只要想明白了这两个变量后面就好理解了。利用了reduce递加返回最大值的形式,在每一次都判断当前字符是否大于上一次出现的重复字符的位置,如果大于的话就取当前字符上一次出现的位置,如果不大于就取上一次出现的重复字符的位置,然后再用当前位置减去这个位置,就能得到这个字符串的长度。然后在跟每一次return的最大值做比较,这样最终得到的就是最大值了。
看了一下我自己的做法,在看了一下这位仁兄的做法,感觉思维上的差距真的不是一点半点,所以加油!