题目(难度:中等):
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
解法思想:
通过Map记录字符串里面每个字符是否出现过,以此为判断点,如果出现则在该字符断开,通过下标变量min和max记录子串长度,并不断更新maxlen,直至字符串长度等于len,结束循环,返回maxlen.
代码实现:
package Middle;
import java.util.HashMap;
import java.util.Map;
/**
* Created by lizeyang on 2019/8/28.
* function:无重复字符的最长字串
* input:"abcabcbb"
* output:3 (最长字串为abc)
*/
public class Solution3 {
private static int i=0,len=0;
private int min,max,maxlen=0,gap=0; //min代表小段不重复字符的左端下标,max代表右端下表,maxlen实时更新不重复字符串长度
private int[] ints = new int[2];
Map<Character,Integer> map = new HashMap<>(); //Map用于存储出现过的字符
public int[] IsContainsKey(int min,char ch,char[] chars){
if(map.containsKey(ch)){
// int j = map.get(ch);
// map.put(ch,j++);
max=i;
gap=max-min;
if(gap>maxlen){
maxlen=gap;
}
ints[0]=i;
ints[1]=maxlen;
}
else{
map.put(ch,1);
i++;
if(i<len){
ch=chars[i];
IsContainsKey(min,ch,chars);
}
else{
max=i;
gap=max-min;
if(gap>maxlen){
maxlen=gap;
}
ints[0]=i;
ints[1]=maxlen;
}
}
return ints;
}
public int lengthOfLongestSubString(String s){
char[] chars = s.toCharArray();
char ch;
len = chars.length;
// System.out.print(chars);
// System.out.println(len);
map.put(chars[0],1);
while(i<len){
min = i++;
ch = chars[i];
int[] ints = IsContainsKey(min,ch,chars); //返回i
i=ints[0];
maxlen=ints[1];
if(i==len-1){
break;
}
}
return maxlen;
}
public static void main(String[] args){
Solution3 s3 = new Solution3();
int maxlength = s3.lengthOfLongestSubString("abcacrfgh");
System.out.println(maxlength);
}
}
缺点:
(1)暴力解法,复杂度高;
(2)利用了额外的存储空间;(可能不可避免的会使用)
方法改进:
解题思想:
使用滑动窗口思想,什么是滑动窗口?比如一个字符串 abcdabf ,进入这个队列(窗口)为 abcd ,满足要求,当再进入a时,队列变成了abcda,不符合要求,需要移动这个队列——将左边元素移除,直到满足要求。
时间复杂度O(n)
代码实现:
public int lengthOfLongestSubstring(String s) {
char[] arr = s.toCharArray();
int len = arr.length;
if (len < 1) return 0;
int left = 0, max = 0;
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < len; i++) {
if (map.containsKey(arr[i])) {
left = Math.max(left, map.get(arr[i]) + 1);
}
map.put(arr[i], i);
max = Math.max(max, i - left + 1);
}
return max;
}