在序列1裡面找到最短的子串,覆蓋了序列2裡面的所有元素,不關心順序
阿新 • • 發佈:2018-11-08
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)); } }