滑動窗口
:定義一個窗口left---right
在left----right
這個窗口內元素是不重複的,不斷移動right
並將其值存入hashMap
中,方便進行去重,使用hashMap.contains(key)
即可判斷在當前移動到的位置是否包含了之前窗口中的位置,若發現需要移動窗口的左邊在更新左邊界的位置lefty=Math.max(lweft,map.get(s.char(i)+1)
package KTwoPointers;
import AarrayProblem.Problem1;
import java.util.HashMap;
import java.util.HashSet;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/5/7 0007 11:59
*/
public class Problem3 {
//https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/hua-dong-chuang-kou-by-powcai/
//採用動態規劃
//無重複的最長子串
//dp[i]爲 字符串的前i個元素怒中的最長無重複
//dp[i] dp[i-1]
public int lengthOfLongestSubstring(String s) {
if(s==null||s.length()==0) return 0;
int[] dp = new int[s.length()];
dp[0]=1;
for(int i=1;i<s.length();i++){
//默認的最長子串爲自身
dp[i]=1;
for(int j=0;j<i;j++){
dp[i]=Math.max(dp[i],dp[j]);
}
//從當前位置向前遍歷找,查找在這個位置開始向前樹的連續不重複字符串
int rs = 1;
int j = i-1;
while (j>=0){
if(s.substring(j+1,i+1).contains(s.charAt(j)+"")) break;
else {
rs++;
j--;
}
}
//更新dp[i]
dp[i]=Math.max(dp[i],rs);
}
int max = 0;
for(int i=0;i<s.length();i++) max = Math.max(max,dp[i]);
return max;
}
//這道題主要用到的思想就是:滑動窗口
//什麼是滑動窗口》
//其實就是一個隊列,比如例題中的abcabcbb
//進入這個隊列(窗口)爲abc滿足題目要求。當在進入a時,這時候不滿足要求。
// 所以我們要移動這個隊列!!!
// 如何移動?
//我們只要把隊列的左邊的元素移動出來就行了,直到滿足題目要求!!!!
//一直維持這樣的隊列,找出隊列最長的長度的時候,求出街
public int lengthOfLongestSubstring1(String s){
if(s.length()==0) return 0;
HashMap<Character,Integer> map = new HashMap<>();
int max = 0;
//左側
int left = 0;
for(int i=0;i<s.length();i++){
//在map中包含了i處的元素,則需要移動 left指針
//移除左邊界移動到重複元素的下一個,就是此時重複元素左邊的元素全部拋棄掉了
//加這個left是確保左側已經遍歷過的數據就不需要再次遍歷了,確保不斷向右側遍歷
if(map.containsKey(s.charAt(i))){
//在這裏可能需要更新也可能不需要更新
//若左邊界大於 map中發現包含的重複字符則不需要更細
//否則更新
left = Math.max(left,map.get(s.charAt(i))+1);
}
//將遍歷到窗口中的值
map.put(s.charAt(i),i);
max = Math.max(i-left+1,max);
}
return max;
}
public static void main(String[] args) {
String s = "abba";
Problem3 problem3 = new Problem3();
System.out.println(problem3.lengthOfLongestSubstring1(s));
}
}