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;

}

 

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