无重复字符的最长子串(滑动窗口)
题目:
思路:
一 暴力法:
-
特殊情况,长度为0或者1
-
声明每次位置的最大长度,和最大的最大值(返回值)
-
双层循环,有点暴力
二 滑动窗口:
基本概念:维持一个窗口(可以理解为队列),当新进来的元素与前面的重复,则把重复的元素及之前的元素全部忽略(可以理解为移出队列)。也就形成了窗口在字符串上平滑移动。
本题思路:
-
特殊情况,长度为0返回0
-
新建一个Map<Character,Integer> map,用来查重和移动窗口
-
初始化result,left为0.result记录返回的最大长度,left记录窗口的起始位置。
-
一次遍历:当有重复,更新left
否则put当前数据,并返回更大的值给result.
-
遍历结束,返回结果
先看思路,不看代码去实现,实现后再看。
代码:
暴力法
java
public int lengthOfLongestSubstring(String s) {
if(s.length()==0) return 0;
if(s.length()==1) return 1;
int maxLength = 0;
int result = 1;
for (int i = 0; i < s.length(); i++) {
HashSet set = new HashSet();
set.add(s.charAt(i));
maxLength=1;
for (int j = i+1; j <s.length() ; j++) {
if(!set.contains(s.charAt(j))){
set.add(s.charAt(j));
maxLength++;
result = Math.max(maxLength,result);
}else {
break;
}
}
}
return result;
}
滑动窗口:
java
public int lengthOfLongestSubstring1(String s) {
if(s.length()==0) return 0;
Map<Character,Integer> map = new HashMap<Character,Integer>();
int result=0;
int left = 0;
for (int i = 0; i < s.length(); i++) {
if(map.containsKey(s.charAt(i))){
left = Math.max(left,map.get(s.charAt(i))+1);
}
map.put(s.charAt(i),i);
result = Math.max(result,i-left+1);
}
return result;
}