问题:https://leetcode.com/problems/minimum-window-substring/
给出一个字符串S和一个字符串T,在S中找到最小窗口,其中将包含复杂度为O(n)的T中的所有字符。
示例:
输入:S =“ ADOBECODEBANC”,T =“ ABC” 输出:“ BANC”
我尝试使用滑动窗口技术来提出解决方案,但是我被困在这里。可以帮忙吗?
package com.tryPrep.Strings;
import java.util.HashMap;
public class MinWindowSubstring {
static String minWinSubStr(String s, String t){
HashMap<Character, Integer> tabl = new HashMap<>();
for(char c: t.toCharArray()){
int charCount=0;
if(tabl.containsKey(c))
charCount = tabl.get(c);
tabl.put(c, charCount+1);
}
int begin =0, end =0, counter=tabl.size();
String ans="";
int max=s.length();
while(end < s.length()) {
char endChar = s.charAt(end);
if (tabl.containsKey(endChar)) {
int charCount = tabl.get(endChar);
if (charCount > 0) {
counter--;
tabl.put(endChar, charCount - 1);
}
}
end++;
while (counter == 0) {
if (max > end - begin) {
ans = s.substring(begin, end - begin);
max = ans.length();
}
char beginChar = s.charAt(begin);
if (tabl.containsKey(beginChar)) {
int charCount = tabl.get(beginChar);
if(charCount == 0) {
tabl.put(beginChar, charCount + 1);
counter++;
}
}
begin++;
}
}
return ans;
}
public static void main(String[] args) {
String s = "ADOBECODEBANC";
String t = "ABC";
System.out.println("minWinSubStr M1 : " + minWinSubStr(s, t));
}
}
输出:
minWinSubStr M1 : ADOBEC
我看到当end到达字符串长度时循环变得满意,但此处的计数器仍不为0。您能否指出我要解除封锁的问题是什么?
答案 0 :(得分:1)
问题是当您删除A(在索引0)后增加计数器的数量时。您开始寻找另一个A来弥补这一损失。
ADOBECODEBANC
^ ^
begin end
这样做时,在不知不觉中您的代码没有考虑到B(在索引9),并且结束指针到达了A(在索引10)。
此后,当开始指针到达B(在索引4处)并且您增加了计数器时,结束指针便找不到其他B。
ADOBECODEBANC
^ ^
begin end
因此,您得到的答案为 ADOBEC
当末端指针找到任何必须考虑的字符时,您可以采取的纠正措施,删除该字符的第一个索引并添加最近遇到的那个。
一旦这样做,您就可以轻松地在开始指针遇到该字符时忽略该字符,因为该字符的频率不会受到影响。
这是有效的,因为我们要从头开始缩小窗口,而不是从头开始缩小窗口。
对于您而言,您可以在每次结束指针遇到 tabl 中的任何字符时减少计数器。
现在,当开始指针遇到任何值为负的字符时,不要增加计数器的值,而只需对值加1。
此外,您应该从头到尾打印值。
s.substring(begin, end)
假设在begin = 8和end = 10的情况下
s.substring(8, 10), not s.substring(8, 2)
static String minWinSubStr(String s, String t) {
System.out.println(s);
System.out.println(t);
HashMap<Character, Integer> tabl = new HashMap<>();
for (char c : t.toCharArray()) {
int charCount = 0;
if (tabl.containsKey(c))
charCount = tabl.get(c);
tabl.put(c, charCount + 1);
}
int begin = 0, end = 0, counter = tabl.size();
String ans = "";
int max = s.length();
while (end < s.length()) {
char endChar = s.charAt(end);
if (tabl.containsKey(endChar)) {
int charCount = tabl.get(endChar);
if (charCount > 0) { counter--; } tabl.put(endChar, charCount - 1);
}
end++;
while (counter == 0) {
if (max > end - begin) {
ans = s.substring(begin, end);
max = ans.length();
}
char beginChar = s.charAt(begin);
if (tabl.containsKey(beginChar)) {
int charCount = tabl.get(beginChar);
if(charCount < 0) { tabl.put(beginChar, charCount + 1); } else if (charCount == 0) { tabl.put(beginChar, charCount + 1); counter++; }
}
begin++;
}
}
return ans;
}
突出显示了我已更改的部分。
注意:此代码仅解决您的用例,并且不应在所有测试用例上提供AC 。