LeetCode Minimum Window Substring

来源:互联网 发布:下载教育平台软件 编辑:程序博客网 时间:2024/05/16 15:49

路走了一半,后半场的第一题,感觉有点似曾相识,细节都忘了。用了开始的第一种方法尝试了一下,也改了几次呢,最终还是败在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;}
下面的方法是看别人的思路 http://www.cnblogs.com/lichen782/p/leetcode_minimum_window_substring_3.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);elsereturn string("");}
终于AC了,长舒一口气,想看一下提交了多少次,确被运行时间吸引了,652ms,可不少,这还O(N)呢,于是试了试别人的 http://blog.csdn.net/doc_sgl/article/details/12395759 这个大神的,结果是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);elsereturn string("");}

0 0
原创粉丝点击