`
bcyy
  • 浏览: 1831038 次
文章分类
社区版块
存档分类
最新评论

Leetcode Minimum Window Substring

 
阅读更多


Minimum Window Substring

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.

这又是属于繁题,需要处理的情况很多,一不小心就会出错。

本题思路:

利用两个表,以字母为下标,一个记录字母出现的总次数,一个记录当前搜索中出现字母的次数

处理情况:

1 出现重复子字符的情况,中间的重复字符不需要特殊处理,只需要处理最左边的重复字符,最左边的指标往右走。

2 记录当前出现了多少个合法子字符,多次重复出现的算不合法字符,如果合法字符等于子字符长度,那么就是找到一个窗口了。

分情况处理,其实很困难,到底如何可以淡定地应付这一类型的题目呢,目前还没找到很轻松的办法。

string minWindow(string S, string T) 
	{
		int fixedTable[256] = {0};
		int countingTable[256] = {0};

		int tn = T.length();
		for (int i = 0; i < tn; i++)
		{
			fixedTable[T[i]]++;
		}

		int minLen = INT_MAX, len = 0;
		int Tcount = 0;
		int sn = S.length();
		string rs("");

		//查找子字符串开始的位置
		int start = 0;
		while (start < sn && fixedTable[S[start]] == 0) start++;

		for (int i = start; i < sn; i++)
		{
			len++;
			//查找到相等字符的时候处理
			if (fixedTable[S[i]] != 0)
			{
				//查找到就++
				countingTable[S[i]]++;
				//处理中间重复字符不计算的情况:
				if (countingTable[S[i]] <= fixedTable[S[i]])
				{
					Tcount++;
				}
				//增加一个计数,Tcount用来判断是否出现了所有子字符
				//处理找到的情况:
				if (Tcount == tn)
				{
					if (len < minLen)
					{
						minLen = len;
						//substr用法,后面的是长度
						rs = S.substr(i-len+1, len);
					}

					//最左边的字符数减一
					countingTable[S[i-len+1]]--;
					len--;
					Tcount--;
					//lend==0的时候就是所有字符都减完了,比如在T.length()==1的时候。
					while (len>0 && fixedTable[S[i-len+1]] == 0)
					{
						len--;
					}
				}

				//只需要判断最左边的字符是否重复就可以了
				while (countingTable[S[i-len+1]] > fixedTable[S[i-len+1]])
				{
					//最左边重复字符去掉
					countingTable[S[i-len+1]]--;
					//Tcount--;最左边重复字符没有计算在Tcount中,不用--
					len--;

					//非T字符去掉
					while (fixedTable[S[i-len+1]] == 0)
					{
						len--;
					}
				}
			}//if (fixedTable[S[i]] != 0)
		}

		return rs;
	}

下面是我一开始写了的程序,这个程序我假定了中间不会包含重复字符的,所以没通过。

不过题目要求改一改,就用得上这个程序了,故此保留。

//中间不能有重复的程序
	string minWindow2(string S, string T) 
	{
		int fixedTable[256] = {0};
		int countingTable[256] = {0};

		int tn = T.length();
		for (int i = 0; i < tn; i++)
		{
			fixedTable[T[i]]++;
		}

		int minLen = INT_MAX, len = 0;
		int Tcount = 0;
		int sn = S.length();
		string rs("");

		//查找子字符串开始的位置
		int start = 0;
		while (start < sn && fixedTable[S[start]] == 0) start++;

		for (int i = start; i < sn; i++)
		{
			len++;
			//查找到相等字符的时候处理
			if (fixedTable[S[i]] != 0)
			{
				//查找到就++
				countingTable[S[i]]++;
				Tcount++;
				//小于等于固定table说明,是合法增加的子字符
				if (countingTable[S[i]] <= fixedTable[S[i]])
				{
					//增加一个计数,Tcount用来判断是否出现了所有子字符
					if (Tcount == tn)
					{
						if (len < minLen)
						{
							minLen = len;
							//substr用法,后面的是长度
							rs = S.substr(i-len+1, len);
						}

						//最左边的字符数减一
						countingTable[S[i-len+1]]--;
						len--;
						Tcount--;
		//lend==0的时候就是所有字符都减完了,比如在T.length()==1的时候。
						while (len>0 && fixedTable[S[i-len+1]] == 0)
						{
							len--;
						}
					}
				}
				//重复字符出现次数过多
				else
				{
					while (S[i-len+1] != S[i])
					{
						if (fixedTable[S[i-len+1]])
						{
							//注意:别忘记处理countingTalbe
							countingTable[S[i-len+1]]--;
							Tcount--;
						}
						len--;
					}
					//注意三个标志:len, Tcount和countingTable都别忘记处理了
					countingTable[S[i]]--;
					//等于和不等于的时候,都需要进一步处理len和Tcount
					len--;
					Tcount--;

					while (fixedTable[S[i-len+1]] == 0)
					{
						len--;
					}
				}
			}//if (fixedTable[S[i]] != 0)
		}

		return rs;
	}



//2014-2-11 update
	string minWindow(string S, string T) 
	{
		int A[256] = {0};
		int B[256] = {0};
		for (int i = 0; i < T.length(); i++) A[T[i]]++;//T[i] or T[i]-'a'
		int c = 0;
		int begin = 0, len = INT_MAX;

		int i = 0;
		while (i < S.length() && !A[S[i]]) i++;

		for (int j = i; j < S.length(); j++)
		{
			if (A[S[j]])
			{
				B[S[j]]++;
				if (B[S[j]] <= A[S[j]])
				{
					if (++c == T.length())//founded
					{
						if (len > j-i+1)//save result
						{
							begin = i; 
							len = j-i+1;
						}
						--c; --B[S[i]]; 
						for (++i; i<j && (!A[S[i]] || A[S[i]] < B[S[i]]); ++i)
							if (A[S[i]]) B[S[i]]--;//i<j防止越界
					}
				}
				else if (S[j] == S[i])//handle repeated
				{
					B[S[i]]--;
					for (++i; i<j && (!A[S[i]] || A[S[i]] < B[S[i]]); ++i)
						if (A[S[i]]) B[S[i]]--;
				}
			}//if (A[idx])...
		}//for (int j = i;...
		return INT_MAX == len? "":S.substr(begin, len);//当T.length() > S.length()
	}





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics