题目:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
题解:
看到判断是否重复,我们首先应该想到Set,因为Set存储的是无重复的、无排序的元素。假如看到统计元素的个数,首先应该想到Map,只有使用了对的数据结构,才能使得我们的代码的运行效率更高,时间复杂度更低。在空间和时间的取舍上,我们一贯的思维是空间换时间,毕竟韶光易逝不复返,但机器硬件我们是可以堆砌出来的。
在计算器网络中,滑动窗口机制相信我们都有所了解,它是TCP/IP的可靠传输的保证机制。子串的含义是字符之间的位置要是连续的、有序的(相对位置不变),这恰恰符合滑动窗口的思想。所以,接下里我们就来是滑动窗口算法来解决此题。
1.使用Set来判断字符是否有重复
2.假如字符有重复,那么就将窗口的左边界移到到重复字符的下一个位置,这样就能保证窗口中的字符构成的是无重复字符的、有序的子串。下面上代码:
Java版本
public int lengthOfLongestSubstring(String s) { if(s == null || s.length() == 0) return 0; int maxLen = 0; for(int i=0;i<s.length();i++){ //滑动窗口 Set Set<Character> set = new HashSet<Character>();//判断是否有重复 set.add(s.charAt(i)); for(int j=i+1;j<s.length();j++){ char c= s.charAt(j); if(!set.contains(c)) set.add(c); else{//有重复的元素 maxLen = Math.max(maxLen,set.size()); //删除重复的元素,即将窗口的左边界移到到重复字符的下一个位置 while(set.contains(c)){ set.remove(s.charAt(i++)); } set.add(c); } } maxLen = Math.max(maxLen,set.size()); } return maxLen; }
JS版本
var lengthOfLongestSubstring = function(s){ if(!s || s.length ==0){ return 0; } var j =0,i = 0,maxLen = 0; var set = new Set(); for(i;i < s.length;i ++){ if(!set.has(s[i])){ set.add(s[i]); maxLen = Math.max(maxLen,set.size); }else{//将窗口的左边界移到到重复字符的下一个位置 while(set.has(s[i])){ set.delete(s[j]); j++; } set.add(s[i]); } } }