algorithm - Minimum window width in string x that contains all characters in string y - Stack Overfl

Given a set T of characters and a string S, find the minimum window in S which will contain all the characters in T in complexity  O ( n ).

eg,
S = “ADOBECODEBANC”
T = “ABC”

Minimum window is “BANC”.

time: O(n) (One pass)

space: O(k)


原来我也认为是用hash表,但是实现时候发现用hash表复杂度显然不是O(n)啊, 是O(mn)

后来在stackoverflow上看到别人解题思路,不得不佩服那个人的想法!


To help illustrate this approach, I use a different example: S = “acbbaca” and T = “aba“. The idea is mainly based on the help of two pointers (begin and end position of the window) and two tables (needToFind andhasFound) while traversing SneedToFind stores the total count of a character in T and hasFound stores the total count of a character met so far. We also use a count variable to store the total characters in T that’s met so far (not counting characters where hasFound[x] exceeds needToFind[x]). When count equals T‘s length, we know a valid window is found.

Each time we advance the end pointer (pointing to an element x), we increment hasFound[x] by one. We also increment count by one if hasFound[x] is less than or equal to needToFind[x]. Why? When the constraint is met (that is, count equals to T‘s size), we immediately advance begin pointer as far right as possible while maintaining the constraint.

How do we check if it is maintaining the constraint? Assume that begin points to an element x, we check if hasFound[x] is greater than needToFind[x]. If it is, we can decrement hasFound[x] by one and advancing begin pointer without breaking the constraint. On the other hand, if it is not, we stop immediately as advancing begin pointer breaks the window constraint.

Finally, we check if the minimum window length is less than the current minimum. Update the current minimum if a new minimum is found.

Essentially, the algorithm finds the first window that satisfies the constraint, then continue maintaining the constraint throughout.

想法就是记录搜索到目前为止某个字符出现次数是否大于需要其出现的次数。

根据hasFound和needToFind

如果用hash表还需要区分是否有重复字符出现的情况,那就是个悲剧哇。

想到的人真牛!


int getMinimumWindow(char *str,char *ptn)
{
	int needToFind[256]={0};
	int hasFound[256]={0};

	int lenp=strlen(ptn);
	int lens=strlen(str);



	int count=0;

	for (int i=0;i<lenp;i++)
	{
		needToFind[ptn[i]]++;
	}
	int begin=0;
	int maxlen=lens;
	for(int end=0;end<lens;end++)
	{
		if (needToFind[str[end]]==0)
		{
			continue;
		}
		hasFound[str[end]]++;
		if (hasFound[str[end]]<=needToFind[str[end]])
		{
			count++;
		}

		if(count==lenp)
		{
			while(needToFind[str[begin]]==0 || hasFound[str[begin]]>needToFind[str[begin]])
			{
				if(hasFound[str[begin]]>needToFind[str[begin]])
					hasFound[str[begin]]--;
				begin++;
			}
			int len=end-begin+1;
			if(maxlen>len)
			{
				maxlen=len;
			}
			//以下三行源程序中没有,自己加的,我觉得是需要的吧,不然怎么知道是否需要更新呢。
			count--;
			hasFound[str[begin]]--;
			begin++;
		}
	}

	return maxlen;
}


参考:http://leetcode.com/2010/11/finding-minimum-window-in-s-which.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值