首页 > 代码库 > [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"
.
Note:
If there is no such window in S that covers all characters in T, return the emtpy string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
Hide Tags
Hash Table Two Pointers String 在字符串 S 中查找最小的窗口,使窗口中全部包含字符串T 中的字符,(不按顺序),需要注意的地方:
- T 中的字符可以重复,窗口需要重复包含。
- 测试 实验中的是SCII字符 ,所以可以用128位数组代替 hash table。
- leetcode c++ 中不能用 hash_map。
思路:
- 使用一个映射int need(hash table 或者 128位数组) 存储T中个字符需要的个数,因为需求可能为负,所以用int。
- 使用一个映射bool exitst(hash table 或者 128位数组) 存储T中个字符是否存在,使用hashtable 也构造这个,因为find 是遍历查找的。
- 用一个var 记录窗口中符合T 中char 的个数。
- 用下表start、last 标记窗口位置,start 指向窗口内第一个char,last 指向窗口外右边第一个char(包括结尾)。
- 每次循环加入或删除(记录一个flag)一个字符,如果不存在便继续循环。
- 通过判断加入删除flag进行操作,更新need 表,更新var, 如果等于T 的长度,更新返回记录。
- 循环结束判断能否查找。
下面是我写的,需要的时间复杂度为O(length(S)),即O(n),空间复杂度为O(length(T)):
1 #include <string> 2 #include <hash_map> 3 #include <iostream> 4 #include <map> 5 using namespace std; 6 using namespace __gnu_cxx; 7 8 class Solution { 9 public:10 string minWindow(string S, string T) {11 int numS = S.length(),numT = T.length();12 if(numS<1||numT<1) return "";13 int WinStart=0,WinLast=0,WinCount =0,retStart,leng=INT_MAX;14 hash_map<char, int > need;15 hash_map<char, bool > exist;16 for(int i =0;i<numT;i++){17 need[T[i]]++;18 exist[T[i]] = true;19 }20 21 bool addorminus;22 char curchar;23 while(WinStart<=numS-numT){24 if(WinCount!=numT&&WinLast<numS){25 addorminus = true;26 curchar = S[WinLast++];27 }28 else{29 addorminus = false;30 curchar = S[WinStart++];31 }32 if(!exist[curchar]) continue;33 if(addorminus){34 if(need[curchar]>0) WinCount++;35 need[curchar]--;36 if(WinCount==numT&&leng>WinLast - WinStart){37 retStart = WinStart;38 leng = WinLast - WinStart;39 }40 }41 else{42 if(WinCount==numT&&leng>WinLast - WinStart+1){43 retStart = WinStart-1;44 leng = WinLast - WinStart+1;45 }46 need[curchar] ++;47 if(need[curchar]>0) WinCount--;48 }49 }50 if(leng==INT_MAX)51 return "";52 return S.substr(retStart,leng);53 }54 };55 56 int main()57 {58 string s = "1A123BAC1";59 string t = "AABC";60 Solution sol;61 62 string ret = sol.minWindow(s,t);63 cout<<ret<<endl;64 return 0;65 }
leetcode 讨论里面有另外一个实现,也是O(n),实现类似,不同的是循环内是通过判断窗口中已经有T中字符的个数来进行 add or delete,我写的是通过目标操作字符来进行,逻辑上没有ta写的方便。
https://oj.leetcode.com/discuss/10337/accepted-o-n-solution
1 class Solution { 2 public: 3 string minWindow(string S, string T) { 4 if (S.empty() || T.empty()) 5 { 6 return ""; 7 } 8 int count = T.size(); 9 int require[128] = {0};10 bool chSet[128] = {false};11 for (int i = 0; i < count; ++i)12 {13 require[T[i]]++;14 chSet[T[i]] = true;15 }16 int i = -1;17 int j = 0;18 int minLen = INT_MAX;19 int minIdx = 0;20 while (i < (int)S.size() && j < (int)S.size())21 {22 if (count)23 {24 i++;25 require[S[i]]--;26 if (chSet[S[i]] && require[S[i]] >= 0)27 {28 count--;29 }30 }31 else32 {33 if (minLen > i - j + 1)34 {35 minLen = i - j + 1;36 minIdx = j;37 }38 require[S[j]]++;39 if (chSet[S[j]] && require[S[j]] > 0)40 {41 count++;42 }43 j++;44 }45 }46 if (minLen == INT_MAX)47 {48 return "";49 }50 return S.substr(minIdx, minLen);51 }52 };
[LeetCode] Minimum Window Substring
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。