1. 程式人生 > >在序列1裡面找到最短的子串,覆蓋了序列2裡面的所有元素,不關心順序

在序列1裡面找到最短的子串,覆蓋了序列2裡面的所有元素,不關心順序

package LeetCode;
import java.util.HashMap;

//Given a string S and a string T, find the minimum window in S
// which will contain all the characters in T in complexity O(n).
//For example,
//S ="ADOBECODEBANC"
//T ="ABC"
//Minimum window is"BANC".
//解決思路:用一個滑動視窗,兩個首尾指標,
//一個雜湊表,初始化為待尋找的字元及待尋找的字元數(value表示T的字元次數與滑動視窗中的字元次數的差值)
//滑動視窗一開始在最左邊,當沒有包含T時,右指標向右移;
//當包含了T時,記錄下視窗大小,與Min對比;左指標右移一位,繼續迴圈
//線上做題網址:https://www.nowcoder.com/questionTerminal/c466d480d20c4c7c9d322d12ca7955ac
//
//這道題的思路是:
//1) begin開始指向0, end一直後移,直到begin - end區間包含T中所有字元。
//記錄視窗長度d
//2) 然後begin開始後移移除元素,直到移除的字元是T中的字元則停止,此時T中有一個字元沒被
//包含在視窗,
//3) 繼續後移end,直到T中的所有字元被包含在視窗,重新記錄最小的視窗d。
//4) 如此迴圈知道end到S中的最後一個字元。
//時間複雜度為O(n)
public class Minimum_window_subString {
    public HashMap<Character, Integer> HashChar = new HashMap<Character, Integer>();

    public String minWindow(String S, String T) {
        if (S == null || T == null || S.length() < T.length())
            return "";
        for (int i = 0; i < T.length(); i++) {
            if (!HashChar.containsKey(T.charAt(i)))
                HashChar.put(T.charAt(i), 1);
            else {
                int value = HashChar.get(T.charAt(i));
                HashChar.put(T.charAt(i), value + 1);
            }
        }
        int start = 0;
        int end = 0;
        int min = Integer.MAX_VALUE;
        int remain = T.length();//計數器來顯示還有多少字元需要找 (remain==0時表示滑動視窗包含T中所有字元)
        String res = "";
        while (end <= (S.length() - 1)) {
            if (HashChar.containsKey(S.charAt(end))) {
                int value = HashChar.get(S.charAt(end));
                HashChar.put(S.charAt(end), value - 1);
                if (value > 0)//如果視窗滑動後,尾部增加的字元屬於T,且檢測到視窗中需要找的屬於T的該字元的個數還沒夠,那麼remain--
                    remain--;
            }
            while (remain == 0) {
                if (min > end - start + 1) {
                    min = end - start + 1;
                    res = S.substring(start, start + min);
                }

                if (HashChar.containsKey(S.charAt(start))) {
                    int value = HashChar.get(S.charAt(start));
                    HashChar.put(S.charAt(start), value + 1);
                    if (value == 0)
                        remain++;
                }
                start++;

            }
            end++;

        }
        return res;

    }

    public static void main(String[] args) {
        String S = "cabwefgewcwaefgcf";
        String T = "cae";
        System.out.println(new Minimum_window_subString().minWindow(S, T));
    }

}