Skip to content

Latest commit

 

History

History
executable file
·
219 lines (210 loc) · 6.7 KB

76. Minimum Window Substring.md

File metadata and controls

executable file
·
219 lines (210 loc) · 6.7 KB

76. Minimum Window Substring

Question

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).

Example:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"

Thinking:

  • Method 1:双指针 TLE
class Solution {
    public String minWindow(String s, String t) {
        if(s == null || t == null) return "";
        int min = Integer.MAX_VALUE;
        String result = "";
        int sLen = s.length();
        int tLen = t.length();
        char[] sArr = s.toCharArray();
        char[] tArr = t.toCharArray();
        Map<Character, Integer> cmp = new HashMap<>();
        for(int i = 0; i < tLen; i++)
            cmp.put(tArr[i], cmp.containsKey(tArr[i]) ? cmp.get(tArr[i]) + 1: 1);
        for(int i = 0; i <= sLen - tLen; i++){
            if(!cmp.containsKey(sArr[i])) continue;
            Map<Character, Integer> temp = new HashMap<>();
            temp.put(sArr[i], 1);
            if(check(temp, cmp)){
                result = s.substring(i, i + 1);
                min = 1;
                return result;
            }
            for(int j = i + 1; j < sLen; j++){
                if(!cmp.containsKey(sArr[j])) continue;
                temp.put(sArr[j], temp.containsKey(sArr[j])?temp.get(sArr[j]) + 1: 1);
                if(check(temp, cmp)){
                    if(j - i + 1 < min){
                        min = j - i + 1;
                        result = s.substring(i, j + 1);
                    }
                    break;
                }
            }
        }
        return result;
    }
    private static boolean check(Map<Character, Integer> sMap, Map<Character, Integer> tMap){
        Set<Character> set = tMap.keySet();
        for(Character c : set){
            if(!sMap.containsKey(c)) return false;
            else
                if(sMap.get(c) < tMap.get(c)) return false;
        }
        return true;
    }
}
  • Method 2: 滑动窗口
class Solution {
    public String minWindow(String s, String t) {
        if(s == null || t == null) return "";
        int[] sMap = new int[256];
        int[] tMap = new int[256];
        int sLen = s.length();
        int tLen = t.length();
        for(int i = 0; i < tLen; i++)
            tMap[t.charAt(i)]++;
        int right = 0;
        String result = "";
        int min = Integer.MAX_VALUE;
        for(int i = 0; i <= sLen - tLen; i++){
            while(right < sLen && !check(sMap, tMap)){
                sMap[s.charAt(right)]++;
                right++;
            }
            if(check(sMap, tMap) && min > right - i + 1){
                min = right - i + 1;
                result = s.substring(i, right);
            }
            sMap[s.charAt(i)]--;
        }
        return result;
    }
    private boolean check(int[] sMap, int[] tMap){
        for(int i = 0; i < sMap.length; i++){
            if(tMap[i] > sMap[i])
                return false;
        }
        return true;
    }
}

二刷

这道题还是借鉴了一刷时候的结果,我先写出来了双指针的方法,最后一个test case无法通过。所以换成了滑动窗口的解法,最后AC。

class Solution {
    public String minWindow(String s, String t) {
        if(s == null || t == null) return "";
        String result = "";
        int res = s.length() + 1;
        int[] tMap = new int[128];
        char[] sArr = s.toCharArray();
        char[] tArr = t.toCharArray();
        for(int i = 0; i < tArr.length; i++)
            tMap[tArr[i]]++;
        int[] cmp = new int[128];
        int right = 0;
        for(int i = 0; i <= sArr.length - tArr.length; i++){
            while(right < sArr.length && !same(tMap, cmp)){
                cmp[sArr[right++]]++;
            }
            if(same(tMap, cmp) && right - i + 1 <= res){
                res = right - i + 1;
                result = s.substring(i, right);
            }
            cmp[sArr[i]]--;
        }
        return result;
    }
    private boolean same(int[] a, int[] b){
        for(int i = 0; i < 128; i++)
            if(a[i] != 0 && b[i] < a[i])
                return false;
        return true;
    }
}

Third Time

  • Method 1: Sliding Window
     class Solution {
     	public String minWindow(String s, String t) {
     		if(s.length() < t.length()) return "";
     		int slow = 0, matchNum = 0, minLen = Integer.MAX_VALUE, index = 0;
     		Map<Character, Integer> wordDict = constructMap(t);
     		for(int fast = 0; fast < s.length(); fast++){
     			char c = s.charAt(fast);
     			if(!wordDict.containsKey(c)) continue;
     			int freq = wordDict.get(c);
     			wordDict.put(c, freq - 1);
     			if(freq == 1){
     				matchNum++;
     			}
     			while(matchNum == wordDict.size()){
     				if(fast - slow + 1 < minLen){
     					minLen = fast - slow + 1;
     					index = slow;
     				}
     				char left = s.charAt(slow++);
     				if(!wordDict.containsKey(left)) continue;
     				int count = wordDict.get(left);
     				wordDict.put(left, count + 1);
     				if(count == 0){  //0->1
     					matchNum--;   
     				}
     			}
     		}
     		return minLen == Integer.MAX_VALUE ? "": s.substring(index, index + minLen);
     	}
     	private Map<Character, Integer> constructMap(String t){
     		Map<Character, Integer> map = new HashMap<>();
     		for(char c : t.toCharArray()){
     			map.put(c, map.getOrDefault(c, 0) + 1);
     		}
     		return map;
     	}
     }

Amazon Session

  • Method 1: Sliding window
    class Solution {
        public String minWindow(String s, String t) {
            if(s.length() < t.length()) return "";
            Map<Character, Integer> map = constructMap(t);
            int slow = 0, matchNum = 0, minLen = Integer.MAX_VALUE, index = 0;
            char[] arr = s.toCharArray();
            for(int fast = 0; fast < arr.length; fast++){
                char c = arr[fast];
                if(!map.containsKey(c)) continue;
                int freq = map.get(c);
                map.put(c, freq - 1);
                if(freq == 1){
                    matchNum++;
                }
                while(matchNum == map.size()){
                    if(fast - slow + 1 < minLen){
                        minLen = fast - slow + 1;
                        index = slow;
                    }
                    char left = arr[slow++];
                    if(!map.containsKey(left)) continue;
                    int count = map.get(left);
                    map.put(left, count + 1);
                    if(count == 0) matchNum--;
                }
            }
            return minLen == Integer.MAX_VALUE ? "": s.substring(index, index + minLen);
        }
        private Map<Character, Integer> constructMap(String t){
            char[] arr = t.toCharArray();
            Map<Character, Integer> map = new HashMap<>();
            for(char c : arr){
                map.put(c, map.getOrDefault(c, 0) + 1);
            }
            return map;
        }
    }