Problem03 無重複的最長子串

無重複的最長子串>>>

在這裏插入圖片描述

滑動窗口:定義一個窗口left---rightleft----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));
    }


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章