leetcode.76 最小覆盖子串

76. 最小覆盖子串

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:

输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"

说明:

  • 如果 S 中不存这样的子串,则返回空字符串 ""
  • 如果 S 中存在这样的子串,我们保证它是唯一的答案

1. 注意到题目的关键:"所有字母的最小子串",也就是说两个串都只能是字母。
2. 于是,可以开辟一个大小为64的数组,来存放数组中字母的频率(Frequency)。准确的说,
   通过字母的ASCII码作为数组的索引,开辟空间的大小为26+6+26=58:26个大写字母,26个小写字母,
   还有中间的6个非字母  A~Z[65~90]  非字母[91~96]  a~z[97~122]
3. 滑动窗口的使用:分三种情况来移动窗口:(这里令当前窗口的左右边界分别为l,r,窗口的大小为winSize=r-l+1)
   1) 当winSize < t.size()  r++;  也就是窗口右边界向右移动
   2) 当winSize == t.size() :
       2.1) 当窗口中的字符已经符合要求了,直接返回return,已经找到了
       2.2) 否则r++,窗口右边界向右移动
   3) 当winSize > t.size()
       3.1) 当窗口中的字符已经符合要求了,l++,窗口左边界向右移动
       3.2) 否则r++,窗口右边界向右移动

 

#include <iostream>
#include <cstring>

using namespace std;

//   1) 当winSize < t.size()  r++;  也就是窗口右边界向右移动
//   2) 当winSize == t.size() :
//	   2.1) 当窗口中的字符已经符合要求了,直接返回return,已经找到了
//	   2.2) 否则r++,窗口右边界向右移动
//   3) 当winSize > t.size()
//	   3.1) 当窗口中的字符已经符合要求了,l++,窗口左边界向右移动
//	   3.2) 否则r++,窗口右边界向右移动

string minWindow(string s, string t) {

	int l = 0, r = -1;
    int sFreq[64] = {0};
    int tFreq[64] = {0};
    int minl = 0, minr = s.size() + 1;
    int flag;
    int i;

    if(s.size() < t.size()){
    	return "";
    }
    for(i = 0; i < t.size(); i++){
    	tFreq[t[i] - 'A']++;
    }

    while(true){
    	if(r - l + 1 < t.size()){
    		r++;
    		sFreq[s[r] - 'A']++;
    		continue;
    	}
    	flag = 0;
    	for(i = 0; i < 64; i++){
    		if(sFreq[i] < tFreq[i]){
    			break;
    		}
    	}
    	if(i == 64){
    		flag = 1;
    	}
    	else{
    		flag = 0;
    	}

    	if(r - l + 1 == t.size()){
    		if(flag == 1){
    			minl = l;
    			minr = r;
    			break;
    		}
    		else{
    			r++;
		    	if(r >= s.size()){
		    		break;
		    	}    			
    			sFreq[s[r] - 'A']++;
    			continue;
    		}
    	}

    	if(r - l + 1 > t.size()){
    		if(flag == 1){
    			if(r - l < (minr - minl)){
    				minr = r;
    				minl = l;
    			}
    			sFreq[s[l] - 'A']--;
    			l++;
    		}
    		else{
    			r++;
		    	if(r >= s.size()){
		    		break;
		    	}    
    			sFreq[s[r] - 'A']++;
    		}

    	}

    }

    if(minr == s.size() + 1){
    	return "";
    }
    return string(s.begin() + minl, s.begin() + minr + 1);
}

int main(){

	string s = "AB";
	string t = "B";
	string re = minWindow(s, t);
	cout << re << endl;
	return 0;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章