关闭

LeetCode76——Minimum Window Substring

标签: leetcodemap
792人阅读 评论(0) 收藏 举报
分类:

LeetCode76——Minimum Window Substring

以前似乎做过类似的,点了LeetCode类似题想起来了(这点把不同类型的题目分类真心不错)

好了,跟LeetCode30——Substring with Concatenation of All Words很相似,需要维护一个Map。

当时做这题的时候就感觉自己做得非常不智能,有点像朴素的字符串的模式匹配,效率比较低。

做这题的时候也比较吃力。

言归正传。

--------------------------------------------------------------------------------------------

这题的意思是:

从母串S中找到这样一个子串W,这个子串包含目标T串中的所有字符,并且该子串的长度最短。


思路:

维护两个索引Start 和 End(初值都为0),分别标识 子串W(这里表示Window)的开始位置和结束位置。

下面关键就是判断何时这两个索引要变化。


1.首先如果没有找到map中的单词,End++,继续往后找。


2.如果map中的字母还没找完,且找到了当前字母,则map中当前单词对应的value--(表示找到一个)。


3.当然可能有重复字母,即value减为负了,这样找出来的window包含多余重复字母肯定不是最优,所以我们要记录找到字母个数。


4.一旦找满单词,这个时候Start到End的位置肯定是包含目标T串所有字符的子串W(即Window)


5.但是这个window不是最优的,我们要对start++,排除不在map中的字符(其实就是让Start越过步骤1中跳过的字符),缩小window大小


6.还有需要优化的地方,就是当window中出现重复的字符,这时,map中该字符的value为负了,我们可以向前移动start。


关于第6点,比如说:

母串ABCDDDDDDDA

目标串ABC

那么当End移动到最后一个A时,Start只能停在第一个A处(为了保证Window中包含ABC三个字母)

而当End移动到最后一个A时,此时Window中多一个A(Map中A的值减为负了),这个时候Start就可以往前移动一下,做一步优化。


根据上述6点,代码就很容易了:


class Solution{
public:
	string minWindow(string s, string t){
	    if(s.size()<t.size())
	        return "";
		map<char, int>chrMap;//保存最初的字母
		for (int i = 0; i < t.size(); i++)
		{
			chrMap[ t[i] ]++;
		}
		int start = 0;
		int end = 0;
		int count = 0;//window中包含所需字符的数量
		int minWindowLen = INT_MAX;
		int curWindow;//当前window大小
		int minStart = 0;//当前window最小值时start的位置
		int minEnd = 0;//当前window最小值时end的位置
		map<char, int>tempMap(chrMap.begin(), chrMap.end());//临时map,用于计算
		while (end < s.size())
		{
			if (tempMap.find(s[end]) == tempMap.end())
			{
				end++;
				continue;
			}
			tempMap[s[end]]--;
			if (tempMap[s[end]] >= 0)
				count++;
			if (count == t.size())//找满一次窗口
			{
				while (start != end)
				{
					if (chrMap.find(s[start]) == chrMap.end())//start不在T的map里面
					{
						start++;
						continue;
					}
					if (tempMap[s[start]] < 0)//window中对于同一字符找重了,此时要向前移动并且补上
					{
						tempMap[s[start]]++;
						start++;
						continue;
					}
					else
						break;
				}
				curWindow = end - start + 1;
				//curWindow = min(curWindow, minWindowLen);
				if (curWindow < minWindowLen)
				{
					minWindowLen = curWindow;
					minStart = start;
					minEnd = end;
				}
			}
			end++;
		}
		if (minWindowLen == INT_MAX)
			return "";
		return s.substr(minStart, minWindowLen);
	}
};



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:487123次
    • 积分:11014
    • 等级:
    • 排名:第1531名
    • 原创:582篇
    • 转载:83篇
    • 译文:1篇
    • 评论:41条
    博客专栏
    最新评论