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))。只贴优化的吧,做了几组测试,都通过了。相信是正确的。
自己写的代码,写代码时各种错误呀,提交了十来遍,主要是程序逻辑问题,还有考虑不周。这真是锻炼基本功呀。下面是我的第一次 提交通过的代码,看似简单,我可在while,for,if里里外外,前前后后 迷糊了好久。
就是上面的代码把map改成数组就行了,操作方式都不用变。贴不贴都行,为了完整,还是贴上吧。
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(""); }
相关文章推荐
- LeetCode Online Judge 题目C# 练习 - Minimum Window Substring
- 【leetcode】Minimum Window Substring
- Leetcode -- Minimum Window Substring
- LeetCode 笔记系列16.1 Minimum Window Substring [从O(N*M), O(NlogM)到O(N),人生就是一场不停的战斗]
- Leetcode 76 Minimum Window Substring(最小窗口的子串)
- leetcode: Minimum Window Substring
- leetcode: Minimum Window Substring
- LeetCode(76) Minimum Window Substring
- [leetcode刷题系列]Minimum Window Substring
- [leetcode] Minimum Window Substring
- Minimum Window Substring @LeetCode
- LeetCode: Minimum Window Substring
- [Leetcode] Minimum Window Substring
- minimum_window_substring ——leetcode
- 【leetcode】Minimum Window Substring (hard) ★
- LeetCode: Minimum Window Substring
- Leetcode231: Minimum Window Substring
- leetcode — minimum-window-substring
- LeetCode076 Minimum Window Substring
- [LeetCode]Minimum Window Substring