LeetCode滑動窗口系列秒殺

76. 最小覆蓋子串

class Solution {

    public String minWindow(String s, String t) {

        //needs存儲t的<字符,出現次數>,windows存儲<s中與t中字符相同的字符,出現次數>
        HashMap<Character,Integer> needs = new HashMap<>();
        HashMap<Character,Integer> windows = new HashMap<>();

        //初始化needs
        for(int i=0;i<t.length();i++){
            //needs.getOrDefault(t.charAt(i),0)+1 含義是:needs如果包含t.charAt(i),
            //則取出值+1;不包含取0+1
            needs.put(t.charAt(i),needs.getOrDefault(t.charAt(i),0)+1);
        }

        int left=0;
        int right=0;
        int count=0;
        int minLen= Integer.MAX_VALUE;
        int start=0;
        int end=0;
        while(right <s.length()){
            //獲取字符
            char temp=s.charAt(right);
            //如果是t中字符,在windows裏添加,累計出現次數
            if(needs.containsKey(temp)){
                windows.put(temp,windows.getOrDefault(temp,0)+1);
                //注意:Integer不能用==比較,要用compareTo
                if(windows.get(temp).compareTo(needs.get(temp))==0 ){
                    //字符temp出現次數符合要求,count代表符合要求的字符個數
                    count++;
                }
            }
            //優化到不滿足情況,right繼續前進找可行解
            right++;
            //符合要求的字符個數正好是t中所有字符,獲得一個可行解
            while(count==needs.size()){
                //更新結果
                if(right-left<minLen){
                    start=left;
                    end=right;
                    minLen=end-left;
                }
                //開始進行優化,即縮小區間,刪除s[left],
                char c=s.charAt(left);
                
                //當前刪除的字符包含於t,更新Windows中對應出現的次數,如果更新後的次數<t中出現的次數,符合要求的字符數減1,下次判斷count==needs.size()時不滿足情況,
                if(needs.containsKey(c)){
                    windows.put(c,windows.getOrDefault(c,1)-1);
                    if(windows.get(c)<needs.get(c)){
                        count--;
                    }
                }
                left++;
            }    
        }
        //返回覆蓋的最小串
        return minLen==Integer.MAX_VALUE ? "":s.substring(start,end);

    }
}

438. 找到字符串中所有字母異位詞

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> list = new ArrayList<>();
        int left = 0 , right = 0;
        char[] needs = new char[26];             //相當於hashMap,用於記錄每個字符的個數
        char[] windows = new char[26];
        for (int i = 0; i < p.length(); i++) {
            needs[p.charAt(i)-'a']++;
        }
        //統計符合要求字符個數
        int count =0;
        while(right < s.length()){

            int ch = s.charAt(right)-'a';
            windows[ch]++;
            if (needs[ch] > 0 && needs[ch] >= windows[ch]){
                count++;
            }
            //長度滿足條件
            while( count == p.length()){
                //加入符合要求的結果
                if (right + 1 - left == p.length()){
                    list.add(left);
                }
                //不符合要求,縮小區間
                int ch1 = s.charAt(left)-'a';
                if (needs[ch1] > 0){
                    windows[ch1]--;
                    if ( windows[ch1] < needs[ch1]){
                        count--;
                    }
                }
                left++;
            }
            right++;
        }
        return list;
    }
}

3. 無重複字符的最長子串

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s.length()==0) return 0;
        HashMap<Character,Integer> map = new HashMap<>();
        int left = 0;
        int max = 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);
            max = Math.max(max,i-left+1);
        }
        return max;
    }
}

567. 字符串的排列

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int[] S1 = new int[26];
        int[] S2 = new int[26];
        for(int i = 0;i<s1.length();i++){
            S1[s1.charAt(i)-'a']++;
        }
        int left = 0;
        int right = 0;
        int count = 0;
        while(right<s2.length()){
            int ch = s2.charAt(right) - 'a';
            S2[ch]++;
            if(S1[ch]>0 && S1[ch]>=S2[ch]){
                count++;
            }

            while(count==s1.length()){
                if(s1.length()==right-left+1){
                    return true;
                }

                int ch1 = s2.charAt(left) - 'a';
                if(S1[ch1]>0){
                    S2[ch1]--;
                    if(S2[ch1]<S1[ch1]){
                        count--;
                    }
                }
                left++;
            }
            right++;
        }
        return false;
    }
}

你知道的越多,你不知道的越多。
有道無術,術尚可求,有術無道,止於術。
如有其它問題,歡迎大家留言,我們一起討論,一起學習,一起進步

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