minimum_window_substring ——leetcode

题目:

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 emtpy string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

解法:

首先建立两个表needtofind和hastofind;再建立头尾两个位置指针begin 和 end;详细解释看代码,很清晰。

#include<iostream>
#include<string>
#include <map>
using namespace std;


string minWindow(string S, string T) {
	string res;
	int lenT = T.size();
	int lenS = S.size();
	if(lenS < lenT || lenS == 0)//如果S的长度小于T的长度,那么就不用找了。
		return res;
	map<char, int>needtofind,hastofind;
	for(int i = 0; i < lenT; ++i){
		needtofind[T[i]]++;
	}
	int begin, end;//定义两个位置指针;
	int k = lenT;
	begin = end = 0;
	for(int i = 0; i < lenS; ++i){
		if(T.find(S[i]) == string::npos)//如果不是要找的字母那就跳过找下一个
			continue;
		else {
			hastofind[S[i]]++;
			if(k == lenT)//如果是第一个找到的字母,那就记录位置
				begin = i;
			if(hastofind[S[i]] <= needtofind[S[i]])//当找到的个数小于需要找到的个数时,说明第一个子串还没有找完,
				k--;
			if(k == 0 && hastofind[S[i]] == needtofind[S[i]]){//k == 0;说明第一个子串找到,后面那个主要是保证接下来找的时候,要保证子串的完整;
				end = i;
				res = S.substr(begin,end - begin + 1);
			}
			if(k <= 0){//在找到的子串中寻找更小的子串,比如bba,要找ab,那么就是在子串中寻找。
				end = i;
				int j = begin;
				for(; j < i; ++j){
					if(T.find(S[j]) == string::npos)
						continue;
					if(hastofind[S[j]] > needtofind[S[j]]){//向后移动一个,就要把已经找到的减去一个
						hastofind[S[j]]--;
						continue;
					}
					if(hastofind[S[j]] == needtofind[S[j]]){
						if(j == begin)//如果等于begin,那说明向后移动的哪一个不是和第一个相同的,所以就要跳出。
							break;
						begin = j;
						string tmp = S.substr(begin,end - begin + 1);
						if(tmp.size() < res.size())
							res = tmp;
						break;
					}
					else
						break;				
				}
			}
			
		}
	}
	return res;	
}



int main()
{
	string S("cabwefgewcwaefgcf");
	string T("cae");
	string res = minWindow(S,T);
	cout<<res<<endl;
	cin.get();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值