题目
给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。
示例:
输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"
说明:
如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。
思路1
遍历S作为结果的首字母,确定首字母后从首字母开始往后直到找到完整包含T的区间。超时。
代码1
class Solution {
public String minWindow(String s, String t) {
String res="";
break1:
for(int i=0;i<=s.length()-t.length();i++){
boolean[] used=new boolean[t.length()];
int usedcount=0;
for(int j=0;j<t.length();j++){
if(s.charAt(i)==t.charAt(j)){
used[j]=true;
usedcount++;
break;
}
}
if(usedcount==0){
continue;
}
if(usedcount==t.length()){
res=s.charAt(i)+"";
return res;
}
for(int j=i+1;j<s.length();j++){
if(res.length()!=0 && j-i+1>=res.length()){
continue;
}
for(int k=0;k<t.length();k++){
if(!used[k] && s.charAt(j)==t.charAt(k)){
used[k]=true;
usedcount++;
if(usedcount==t.length()){
if(res.length()==0){
res=s.substring(i,j+1);
}else{
if(j-i+1<res.length()){
res=s.substring(i,j+1);
}else{
}
}
continue break1;
}
break;
}
}
}
}
return res;
}
}
思路2
双指针i,j。初始i=j=0。j++直到完整包含字符串T,初始化结果。然后i++,如果更短则更新结果,直到不包含完整字符串T。继续j++直到完整包含字符串T,如果更短则更新结果。然后i++,如果更短则更新结果,直到不包含完整字符串T。以此类推。
代码2
class Solution {
public String minWindow(String s, String t) {
String res="";
if(s.length()<t.length()){
return res;
}
// map存字符串t所有字母及其数量
Map<Character,Integer> tt=new HashMap<Character,Integer>();
for(int i=0;i<t.length();i++){
if(tt.get(t.charAt(i))==null){
tt.put(t.charAt(i),1);
}else{
tt.put(t.charAt(i),tt.get(t.charAt(i))+1);
}
}
int tcount=t.length();
int i=0;
int j=0;
// 1:i++; 2:j++; -1:i=j=0;
int action=-1;
if(tt.get(s.charAt(0))==null){
}else{
tt.put(s.charAt(0),tt.get(s.charAt(0))-1);
tcount--;
}
while(true){
if(j>=s.length()){
break;
}
if(action==-1){
}else if(action==1){
if(tt.get(s.charAt(i-1))==null){
}else{
tt.put(s.charAt(i-1),tt.get(s.charAt(i-1))+1);
if(tt.get(s.charAt(i-1))<=0){
}else{
tcount++;
}
}
}else if(action==2){
if(tt.get(s.charAt(j))==null){
}else{
if(tt.get(s.charAt(j))<=0){
tt.put(s.charAt(j),tt.get(s.charAt(j))-1);
}else if(tt.get(s.charAt(j))>0){
tt.put(s.charAt(j),tt.get(s.charAt(j))-1);
tcount--;
}
}
}
// s[i]~s[j] 是否完整包含t
if(tcount==0){
if(res.length()==0){
res=s.substring(i,j+1);
}else{
if(res.length()>j-i+1){
res=s.substring(i,j+1);
}else{
}
}
if(res.length()==t.length()){
return res;
}
// 设置下一步
if(action==-1){
action=2;
j++;
}else{
action=1;
i++;
}
}else{
// 设置下一步
if(action==-1){
action=2;
j++;
}else{
action=2;
j++;
}
}
}
return res;
}
}
总结
双指针更快。