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.
[思路]
这道题和Substring with Concatenation of All Words思路非常类似,同样是建立一个字典,然后维护一个窗口。区别是在这道题目中,因为可以跳过没在字典里面的字符(也就是这个串不需要包含且仅仅包含字典里面的字符,有一些不在字典的仍然可以满足要求),所以遇到没在字典里面的字符可以继续移动窗口右端,而移动窗口左端的条件是当找到满足条件的串之后,一直移动窗口左端直到有字典里的字符不再在窗口里。在实现中就是维护一个HashMap,一开始key包含字典中所有字符,value就是该字符的数量,然后遇到字典中字符时就将对应字符的数量减一。算法的时间复杂度是O(n),其中n是字符串的长度,因为每个字符再维护窗口的过程中不会被访问多于两次。空间复杂度则是O(字典的大小),也就是代码中T的长度。
public String minWindow(String S, String T) { int m = S.length(), n = T.length(); Map<Character, Integer> map = new HashMap<>(); for(int i=0; i<n; i++) { char c = T.charAt(i); map.put(c, map.containsKey(c) ? map.get(c)+1 : 1); } int l = 0, r = 0; int minStart = 0, minLen = Integer.MAX_VALUE; int count = 0; for(; r < m; r++) { char rc = S.charAt(r); // right char if(!map.containsKey(rc)) continue; map.put(rc, map.get(rc)-1); if(map.get(rc) >= 0) count++; while(count == n) { int len = r-l+1; if(len < minLen) { minLen = len; minStart = l; } char lc = S.charAt(l); // left char if(map.get(lc) != null) { map.put(lc, map.get(lc)+1); if(map.get(lc)>0) { count--; } } l++; } } if(minLen > m) return ""; return S.substring(minStart, minStart+minLen); }
我们还可以用两个数组来替代HashMap。
public String minWindow(String s, String t) { int[] mapS = new int[256]; int[] mapT = new int[256]; for(char c: t.toCharArray()) { mapT[c]++; } int minLen = Integer.MAX_VALUE; int left = 0, cnt = 0; String res = ""; for(int i=0; i<s.length(); i++) { char c = s.charAt(i); if(++mapS[c] <= mapT[c]) cnt++; if(cnt == t.length()) { c = s.charAt(left); while(mapS[c] > mapT[c]) { mapS[c]--; c = s.charAt(++left); } int len = i-left+1; if(len < minLen) { minLen = len; res = s.substring(left, i+1); } } } return res; }
又重构了下以上代码:
string minWindow(string s, string t) { vector<int> vs(256), vt(256); for(char c:t) { vt[c]++; } int m = s.size(), n = t.size(); int left = 0, cnt = 0, minLen = INT_MAX; string res; for(int i=0; i<m; i++) { vs[s[i]]++; if(!vt[s[i]]) continue; if(vs[s[i]] <= vt[s[i]]) { cnt++; } if(cnt == n) { while(vs[s[left]] > vt[s[left]]) { vs[s[left]]--; left++; } int len = i-left+1; if(len < minLen) { minLen = len; res = s.substr(left, len); } } } return res; }
Reference:
https://shepherdyuan.wordpress.com/2014/08/02/minimum-window-substring/
相关推荐
javascript js_leetcode题解之76-minimum-window-substring.js
python python_leetcode题解之076_Minimum_Window_Substring
由于压缩包子文件的文件名称列表只给出了 "LeetCode76_MinimumWindowSubstring-master",我们可以假设这是一个开源项目或代码仓库的主分支名,通常这样的命名表示这是LeetCode第76题的解决方案,并且使用了Master...
c c语言_leetcode题解之0076_minimum_window_substring.zip
Leetcode.76 Minimum Window Substring Leetcode.438 Find All Anagrams in a String Pattern: two points 双指针是这样的模式:两个指针朝着左右方向移动(双指针分为同向双指针和异向双指针),直到他们有一个或是...
Minimum Window Substring 两个指针遍历 map Maximal Rectangle 栈 局部递增 或者 动态规划 Binary Tree Inorder Traversal 栈 递归 Single Number 异或 Copy List with Random Pointer 单链表 map Max Points on a ...
- Minimum Window Substring: 给定两个字符串s和t,找出s中包含t所有字母的最小子串。 - Remove Duplicates from Sorted Array II: 删除排序数组中的重复项,使得每个元素最多出现两次。 - Search in Rotated Sorted...
411 | [Minimum Unique Word Abbreviation](https://leetcode.com/problems/minimum-unique-word-abbreviation/) | [C++](./C++/minimum-unique-word-abbreviation.cpp) [Python](./Python/minimum-unique-word-...
第76题"最小覆盖子串"(Minimum Window Substring)是其中一道经典的字符串处理问题,它涉及到字符串查找、滑动窗口等算法概念。在这个题解压缩包中,你将找到关于如何使用C++解决这道题目的详细步骤和代码实现。 ...
leetcode添加元素使和等于 经验教训 一定要吧功能尽量细化为函数,这样一者做题思路比较清晰,二者可以在某些情况下直接return值。 如果输入的形式是一个序列,则可以想想:分治、动规、贪婪,一般不建议搜索,因为...
12. **Minimum Window Substring** (Hard): 寻找包含所有给定字符的最小子串。使用双指针和滑动窗口优化搜索过程。 13. **Merge Two Sorted Lists** (Easy): 合并两个已排序的链表。可以通过迭代或递归方法解决,...