leetcode_076 Minimun Window Substring

题目分析:在字符串S中选一个长度最短的子串,使得子串包含所有的字母,要求时间复杂度为O(n),空间复杂度为O(1)。

解题思路:

                   双指针实现,具体如下:

                   尾指针不断向后扫描,当遇到一个窗口包含所有T的字符,则收缩头指针,直到不能收缩头指针为止

                   1)定义两个数组,分别用来统计T字符串中每个字母的个数和当前找到T中每个字母的个数;

                   2)一边遍历S字符串,判断S字符串中是否有T的字母,有则将此位置保存到队列中,更新此字符在找

                        到的次数;

                   3)在2)的基础上,依据情况,更新或不更新子串中找到T中的字母数目;

                   4)依据3)更新后找到T中的字母数判断是否需要收缩头指针;

                   5)在4)的基础上,若收缩了头指针,则判断当前子串长度是否小于之前的子串长度,小则更新,否

                        则不变。

                   6)最后根据头指针是否为-1输出最后的结果。若为-1,则未找到包含字符串T的子串,返回空,否则

                        返回子串。

class Solution
{
	public:
		string minWindow(string s, string t)
		{
			int slen = s.length();
			int tlen = t.length();
			queue<int> Q;
			int srccnt[256] = {0};      //统计T中每个字母的个数 
			int foundcnt[256] = {0};    //当前找到T中每个字母的个数 
			for (int i = 0; i < tlen; i++)
				srccnt[t[i]]++; 
		    int hasfound = 0;           //已经找到的字母数目
			int winstart = -1;
			int winend = slen;
			// 遍历字符串S 
			for (int i = 0; i < slen; i++)
			{
				if (srccnt[s[i]] != 0)
				{
					Q.push(i);
					foundcnt[s[i]]++;
					// 记录截止目前,找到子串T中的字母个数 
					if (foundcnt[s[i]] <= srccnt[s[i]])
						hasfound++;
					// 当找到tlen时,进行收缩 
					if (hasfound == tlen)
					{
						//找到一个满足的窗口
						int k;
						do
						{
							//缩减窗口到最小
							k = Q.front();
							Q.pop();
							foundcnt[s[k]]--; 
						} while (srccnt[s[k]] <= foundcnt[s[k]]);
						// 判断当前情况下子串长度是否为更小,更小则更新,否则不变 
						if (winend - winstart > i - k)
						{
							winstart = k;
							winend = i;
						}
						hasfound--; 
					} 
				}
			} 
			return winstart != -1 ? s.substr(winstart, winend - winstart + 1) : "";
		}
};




                   

你可能感兴趣的:(leetcode_076 Minimun Window Substring)