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 empty string"".
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
方法一:这题也可以套模板,T:O(n), S:O(n) 41ms
public String minWindow(String s, String t) {
if (s == null || t == null || s.isEmpty() || t.isEmpty()) {
return "";
}
HashMap<Character, Integer> targetMap = new HashMap<>();
for (int i = 0; i < t.length(); i++) {
Character c = t.charAt(i);
if (targetMap.containsKey(c)) {
targetMap.put(c, targetMap.get(c) + 1);
} else {
targetMap.put(c, 1);
}
}
int cnt = t.length();
int start = 0;
int min = s.length() + 1;
String result = "";
// loop througth the string and find min length
for (int end = 0; end < s.length(); end++) {
Character c = s.charAt(end);
// expand end pointer to include all char in target
if (targetMap.containsKey(c)) {
if (targetMap.get(c) >= 1) {
cnt--;
}
targetMap.put(c, targetMap.get(c) - 1);
}
// shrink start
while (cnt == 0) {// 这里因为窗口大小不定,所以要一直往左缩到最小
int curLen = end - start + 1;
if (curLen < min) {
min = curLen;
result = s.substring(start, end + 1);
}
Character startChar = s.charAt(start);
if (targetMap.containsKey(startChar)) {
if (targetMap.get(startChar) >= 0) {
cnt++;
}
targetMap.put(startChar, targetMap.get(startChar) + 1);
}
start++;
}
}
return result;
}方法二:用两个HashMap,一个存target另一个用来数数
public String minWindow(String s, String t) {
if (s == null || t == null || s.isEmpty() || t.isEmpty()) {
return "";
}
// collect target string character & it's number
HashMap<Character, Integer> targetMap = new HashMap<>();
for (int i = 0; i < t.length(); i++) {
Character c = t.charAt(i);
if (targetMap.containsKey(c)) {
targetMap.put(c, targetMap.get(c) + 1);
} else {
targetMap.put(c, 1);
}
}
int cnt = 0; // counter for if current we include all char in target array
HashMap<Character, Integer> currentWindow = new HashMap<>();
int start = 0;
int min = s.length() + 1;
String result = "";
// loop througth the string and find min length
for (int end = 0; end < s.length(); end++) {
Character c = s.charAt(end);
// expand end pointer to include all char in target
if (targetMap.containsKey(c)) {
if (currentWindow.containsKey(c)) {
if (currentWindow.get(c) < targetMap.get(c)) {
cnt++;
}
currentWindow.put(c, currentWindow.get(c) + 1);
} else {
currentWindow.put(c, 1);
cnt++;
}
}
// shrink start
if (cnt == t.length()) {
Character startChar = s.charAt(start);
while (!currentWindow.containsKey(startChar) || currentWindow.get(startChar) > targetMap.get(startChar)) {
if (currentWindow.containsKey(startChar) && currentWindow.get(startChar) > targetMap.get(startChar)) {
currentWindow.put(startChar, currentWindow.get(startChar) - 1);
}
start++;
startChar = s.charAt(start);
}
int curLen = end - start + 1;
if (curLen < min) {
min = curLen;
result = s.substring(start, end + 1);
}
}
}
return result;
}public String minWindow(String s, String t) {
if (s == null || t == null) {
return "";
}
HashMap<Character, Integer> target = new HashMap<>();
for (int i = 0; i < t.length(); i++) {
char cur = t.charAt(i);
if (target.containsKey(cur)) {
target.put(cur, target.get(cur) + 1);
} else {
target.put(cur, 1);
}
}
int cnt = t.length();
int min = s.length() + 1;
String res = "";
int start = 0;
for (int end = 0; end < s.length(); end++) {
char endChar = s.charAt(end);
if (target.containsKey(endChar)) {
if (target.get(endChar) > 0) {
cnt--;
}
target.put(endChar, target.get(endChar) - 1);
}
while (cnt == 0) {
int curLen = end - start + 1;
if (curLen < min) {
min = curLen;
res = s.substring(start, end + 1);
}
char startChar = s.charAt(start);
if (target.containsKey(startChar)) {
target.put(startChar, target.get(startChar) + 1);
if (target.get(startChar) > 0) {
cnt++;
}
}
start++;
}
}
return res;
}换个int数组快好多,5ms
public String minWindow(String s, String t) {
if (s == null || s.length() == 0 || t == null || t.length() == 0) {
return "";
}
int[] target = new int[256];
for (int i = 0; i < t.length(); i++) {
target[t.charAt(i)]++;
}
int left = 0;
int min = s.length() + 1;
String res = "";
int cnt = t.length();
for (int right = 0; right < s.length(); right++) {
char rc = s.charAt(right);
if (target[rc] > 0) {
cnt--;
}
target[rc]--;
while (cnt == 0) {
if (right - left + 1 < min) {
min = right - left + 1;
res = s.substring(left, right + 1);
}
char lc = s.charAt(left);
if (target[lc] >= 0) {
cnt++;
}
target[lc]++;
left++;
}
}
return res;
}Previous438 Find All Anagrams in a StringNext159 Longest Substring with At Most Two Distinct Characters
Last updated
Was this helpful?