leetcode Minimum Window Substring

leetcode 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".

解法1:(部分错误的)
维护一个position【256】数组,存放的是字母所在的位置。
从头开始遍历,一单发现S【i】在T中出现,就更新position【S【i】】=i;
如果当前已经找到了所有的T,就比较此时position的最左和最右的位置距离是否比以前记录的最小值小。(可以设置一个left记录,不用遍历所有position)
例如:
S: ABCDEA
T: AE
position【A】开始等于0;
遇到第二个A。position【A】等于5.
和position【B】距离要小于开始的差值5。
所以更新长度。
此题的解法在T没有重复的时候是正确的,但是如果T是重复的,就会出错。
例如:
S: AAB
T: AA
此种解法就失效了。
解法2:
此种解法其实和上解法有点关联。
他维护2个数组和3个int
needFilled【256】记录T中字母的个数。
hasFilled【256】记录的是已经填充的字母的个数。
count 记录的是已经发现的字母个数。
left 记录前指针
right 记录后指针
遍历S数组,如果遍历到right ,needFilled【S【right 】】<=0;说明该字符是不需要的。
如果>0:
hasFilled【S【right】】++;
如果hasFilled【S【right】】<=needFilled【S【right 】】,说明之前还有没有找到全部的T,所以count++;
1.如果hasFilled【S【right】】>=needFilled【S【right 】】,说明之前有多余的元素,那么就从left开始遍历,如果
needFilled【S【right 】】<=0||hasFilled【S【right】】>needFilled【S【right 】】,说明改元素可以不要,因为去掉它,不影响T字符的寻找状态。这样就能减小结果字符串的大小。
如果count==T.size();
比较此时right-left+1和以前最小的结果。如果小于就更新结果。
2.答案此处的逻辑是(和1比较):
如果count==T.size();
那么就从left开始遍历,如果
needFilled【S【right 】】<=0||hasFilled【S【right】】>needFilled【S【right 】】,说明改元素可以不要,因为去掉它,不影响T字符的寻找状态。这样就能减小结果字符串的大小。
比我的逻辑细节处理要好点,因为只有count==T.size()的时候才,需要从left开始去掉多余的。
比如:
S:aaaaaaab
T:ab
我的逻辑是从第二个a开始每次都要从left开始去重,
他的逻辑是遇到b一次去掉所有的重复。
时间复杂度没有变化,但是细节的逻辑还是有差距。
步骤如下图:

i) S = "acbbaca" and T = "aba".

ii) The first minimum window is found. Notice that we cannot advance begin pointer as hasFound['a'] == needToFind['a'] == 2. Advancing would mean breaking the constraint.

iii) The second window is found. begin pointer still points to the first element 'a'. hasFound['a'] (3) is greater than needToFind['a'] (2). We decrement hasFound['a'] by one and advance begin pointer to the right.

iv) We skip 'c' since it is not found in T. Begin pointer now points to 'b'. hasFound['b'] (2) is greater than needToFind['b'] (1). We decrement hasFound['b'] by one and advance begin pointer to the right.

v) Begin pointer now points to the next 'b'. hasFound['b'] (1) is equal to needToFind['b'] (1). We stop immediately and this is our newly found minimum window.

class Solution {
public:
string minWindow(string S, string T) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
int sizeS=S.size();
int sizeT=T.size();
vector<int>hasFilled(256,0);
vector<int>needFilled(256,0);
int count=0;
int restart=0;
int reLength=INT_MAX;
for(int i=0;i<sizeT;i++)
needFilled[T[i]]++;
for(int left=0,right=0;right<sizeS;right++)
{
if(needFilled[S[right]]>0)
{
hasFilled[S[right]]++;
if(hasFilled[S[right]]<=needFilled[S[right]])
count++;
if(hasFilled[S[right]]>=needFilled[S[right]])
while(needFilled[S[left]]<=0||hasFilled[S[left]]>needFilled[S[left]])
{
hasFilled[S[left]]--;
left++;

}

if(count==sizeT)
{
if(right-left+1<reLength)
{
restart=left;
reLength=right-left+1;
}
}
}
}
if(count==sizeT)
return S.substr(restart,reLength);
else
return "";
}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值