[LeetCode] 76. Minimum Window Substring 最小窗口子串
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"
.
Note:
If there is no such window in S that covers all characters in T, return the emtpy string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
用双指针来解决,外层for循环i = 0 ... n, 内层while循环,条件是j < source.length() 和 !isValid(sourceHash, targetHash),检查当前窗口中的substring是否包含了目标字符串中全部所需字符,未满足则继续扩大窗口j++,同时更新sourceHash。这里sourceHash,targetHash是整型数组int[],因为ASCII码最多256个,因此用int[]可以作为简化的HashMap使用,key是char对应的int的值,value则是该char在substring中的出现个数。isValid函数则检查sourceHash是否全部包含了targetHash,256个字符一一对应,因此只需一重for循环,如果sourceHash[i] < targetHash[i],则说明有字符未满足条件。另外要设定一个辅助变量记录minStr的长度。
Java:
public class Solution { public String minWindow(String source, String target) { if (source == null || source.length() == 0 || target == null || target.length() == 0) { return ""; } int[] sourceHash = new int[256]; int[] targetHash = new int[256]; int ans = Integer.MAX_VALUE; String minStr = ""; initTargetHash(targetHash, target); int i = 0; int j = 0; for (i = 0; i < source.length(); i++) { while (j < source.length() && !isValid(sourceHash, targetHash)) { sourceHash[source.charAt(j)]++; if (j < source.length()) { j++; } else { break; } } if (isValid(sourceHash, targetHash)) { if (ans > j - i) { ans = Math.min(ans, j - i); minStr = source.substring(i, j); } } sourceHash[source.charAt(i)]--; } return minStr; } boolean isValid(int[] sourceHash, int[] targetHash) { for (int i = 0; i < sourceHash.length; i++) { if (targetHash[i] > sourceHash[i]) { return false; } } return true; } public void initTargetHash(int[] targetHash, String target) { for (int i = 0; i < target.length(); i++) { targetHash[target.charAt(i)]++; } } }
C++:
class Solution { public: string minWindow(string S, string T) { if (T.size() > S.size()) return ""; string res = ""; int left = 0, count = 0, minLen = S.size() + 1; int tm[256] = {0}, sm[256] = {0}; for (int i = 0; i < T.size(); ++i) ++tm[T[i]]; for (int right = 0; right < S.size(); ++right) { if (tm[S[right]] != 0) { ++sm[S[right]]; if (sm[S[right]] <= tm[S[right]]) ++count; while (count == T.size()) { if (right - left + 1 < minLen) { minLen = right - left + 1; res = S.substr(left, minLen); } if (tm[S[left]] != 0) { --sm[S[left]]; if (sm[S[left]] < tm[S[left]]) --count; } ++left; } } } return res; } };
类似题目:
[LeetCode] 727. Minimum Window Subsequence