滑动窗口
:定义一个窗口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));
}
}