您的位置:首页 > 其它

LeetCode Minimum Window Substring

2014-01-10 22:08 351 查看
路走了一半,后半场的第一题,感觉有点似曾相识,细节都忘了。用了开始的第一种方法尝试了一下,也改了几次呢,最终还是败在time limit exceeded。this feeling is not so bad, just like meeting a good-looking girl that turn you down for the first time, which just increase the feeling of adoration for her thinking she is more
than beautiful outside, but gorgeous inside.

第一种方法:还是最原始的思想,开辟一个长度和T一样的数组,记录每个字符出现的位置。数组中的最大位置和最小位置的差就是当前长度。然后找最小位置的那个字符出现的下一个位置,用其值更新数组中原来的位置,此时重新计算数组中的最小值和最大值,看当前长度是不是小于原来求得的最小长度,若小于的话更新最小长度。不断的迭代,直到找到某个位置返回-1(因为用find函数)说明找到头了,退出循环。当然这样处理时间肯定不是O(N+M),而是O(N)*O(M),做了优化,就是用set来代替数组,因为这样就不用花O(M)的时间找最大最小值了。其实时间是花在插入时了,总时间复杂度还是O(N)*O(log(M))。只贴优化的吧,做了几组测试,都通过了。相信是正确的。

string minWindow2(string S,string T) {
int lenT = T.length();
int lenS = S.length();
if(lenS==0||lenT==0||lenT>lenS)
return string("");
set<int> posSet;
int temppos;
for (int i=0;i<lenT;i++)
{
temppos=S.find(T[i],0);
while(posSet.find(temppos)!=posSet.end())//temppos could not be in the posSet,case of "aa"  "aa"
{
temppos = S.find(T[i],temppos+1);
}
if(temppos==-1)
return string("");
posSet.insert(temppos);
}
if(lenT>lenS)
return S;
int distance,mindis = lenS+1,minStart=0,minEnd=lenT;
while(1)
{
set<int>::reverse_iterator iter_end = posSet.rbegin();
distance = *iter_end - *(posSet.begin()) + 1;
if(distance<mindis)
{
mindis = distance;
minStart = *(posSet.begin());
minEnd = *iter_end;
}
temppos = S.find(S[*(posSet.begin())],*(posSet.begin())+1);
while(posSet.find(temppos)!=posSet.end())
{
temppos = S.find(S[temppos],temppos+1);//temppos = S.find(T[i],temppos+1);
}
if(temppos==-1)
break;
posSet.erase(posSet.begin());
posSet.insert(temppos);
}
return S.substr(minStart,minEnd-minStart+1);
}
测试用例

int _tmain(int argc, _TCHAR* argv[])
{
string S="abc";//"aa";//"ab";//"abbbb";//"ADOBECODEBANC";//"acbbaca";//"cabefgecdaecf";//"bba";//
string T="cba";//"aa";//"a";//"aa";//"ABC";//"aba";//"cae";//"ab";//
cout<<minWindow2(S,T)<<endl;
S="aa";//"ab";//"abbbb";//"ADOBECODEBANC";//"acbbaca";//"cabefgecdaecf";//"bba";//
T="aa";//"a";//"aa";//"ABC";//"aba";//"cae";//"ab";//
cout<<minWindow2(S,T)<<endl;
S="ab";//"abbbb";//"ADOBECODEBANC";//"acbbaca";//"cabefgecdaecf";//"bba";//
T="a";//"aa";//"ABC";//"aba";//"cae";//"ab";//
cout<<minWindow2(S,T)<<endl;
S="ADOBECODEBANC";//"acbbaca";//"cabefgecdaecf";//"bba";//
T="ABC";//"aba";//"cae";//"ab";//
cout<<minWindow2(S,T)<<endl;
S="acbbaca";//"cabefgecdaecf";//"bba";//
T="aba";//"cae";//"ab";//
cout<<minWindow2(S,T)<<endl;
S="cabefgecdaecf";//"bba";//
T="cae";//"ab";//
cout<<minWindow2(S,T)<<endl;
S="bba";//
T="ab";//
cout<<minWindow2(S,T)<<endl;
system("pause");
return 0;
}
下面的方法是看别人的思路 /article/5789866.html

自己写的代码,写代码时各种错误呀,提交了十来遍,主要是程序逻辑问题,还有考虑不周。这真是锻炼基本功呀。下面是我的第一次 提交通过的代码,看似简单,我可在while,for,if里里外外,前前后后 迷糊了好久。

string minWindow3(string S,string T) {
int lenT = T.length();
int lenS = S.length();
if(lenS==0||lenT==0||lenT>lenS)
return string("");
map<char,int> needFound;
map<char,int> hasFound;
for (int i=0;i<lenT;i++)
{
needFound[T[i]]++;
}
int begin=0,end=0;
int count=0;
int distance,mindis=lenS+1;
int minStart=0,minEnd=lenS;
while(end<lenS&&begin<lenS)
{
while(end<lenS&&needFound[S[end]]==0){
end++;
}
if(end==lenS)
break;
hasFound[S[end]]++;
if (hasFound[S[end]]<=needFound[S[end]])
{
count++;
}
while(count==lenT&&hasFound[S[begin]]>needFound[S[begin]]||needFound[S[begin]]==0)
{
hasFound[S[begin]]--;
begin++;
}
if (count==lenT)
{
distance = end - begin + 1;
if(distance<mindis)
{
mindis = distance;
minStart = begin;
minEnd = end;
}
}
end++;
}
if(count==lenT)
return S.substr(minStart,minEnd-minStart+1);
else
return string("");
}
终于AC了,长舒一口气,想看一下提交了多少次,确被运行时间吸引了,652ms,可不少,这还O(N)呢,于是试了试别人的 /article/2750062.html 这个大神的,结果是84ms。怎么回事呢?我倒没仔细看他的程序逻辑,只是看了他没用map,用数组了,所以我就先从这试试吧,结果出来了。



就是上面的代码把map改成数组就行了,操作方式都不用变。贴不贴都行,为了完整,还是贴上吧。

string minWindow4(string S,string T) {
int lenT = T.length();
int lenS = S.length();
if(lenS==0||lenT==0||lenT>lenS)
return string("");
int needFound[256]={0};
int hasFound[256]={0};
for (int i=0;i<lenT;i++)
{
needFound[T[i]]++;
}
int begin=0,end=0;
int count=0;
int distance,mindis=lenS+1;
int minStart=0,minEnd=lenS;
while(end<lenS&&begin<lenS)
{
while(end<lenS&&needFound[S[end]]==0){
end++;
}
if(end==lenS)
break;
hasFound[S[end]]++;
if (hasFound[S[end]]<=needFound[S[end]])
{
count++;
}
while(count==lenT&&hasFound[S[begin]]>needFound[S[begin]]||needFound[S[begin]]==0)
{
hasFound[S[begin]]--;
begin++;
}
if (count==lenT)
{
distance = end - begin + 1;
if(distance<mindis)
{
mindis = distance;
minStart = begin;
minEnd = end;
}
}
end++;
}
if(count==lenT)
return S.substr(minStart,minEnd-minStart+1);
else
return string("");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: