Minimum Window Substring LT76
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).
Example:
Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"
Note:
- If there is no such window in S that covers all characters in T, return the empty string
""
. - If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
Idea 1. Sliding window with two pointers. The right pointer to expand the window while fixing the left window and the left pointer to shrink the given window while fixing the right window. At any time only one of these pointer move and the other remains fixed. 经典的滑动窗口的方法, 用左右2各点滑动形成的窗口中找寻符合条件的窗口。这题麻烦的地方是如何快速的判断符合条件的窗口(letterSeen == T.length),包含T的所有字母的最小窗口, 包含T的所有字母的窗口字母个数和T至少一样长。T中可能有重复字母,需要用map来记下每个字母出现的个数。
如何update letterSeen?
++letterSeen if window[right] <= letterT[right] after ++window[right]
--letterSeen if window[left] < letterT[left] after --window[left]
Time complexity: O(S + T), in the worst case each element is visited twice, once by right pointer, once by the left pointer. (exactly loop time 2 * S + T)
Space complexity: O(T + S), depends on the dictionary size
1.a.建立2个map, 第一个letterT用来记下T中字母出现个数,第二个window记录滑动窗口中字母出现的个数, 判断窗口中出现的字母是不是符合条件的,比如s = "aab", t = "ab", letterT['a' - 'A'] = 1, 当right = 0, window['a'-'A'] = 1 <= 2, T中的字母扫了一个,letterSeen = 1; 当right = 1, window['a'-'A'] = 2 > letterT['a' - 'A'], 扫到的比T中还多,算是多余的,就不能加letterSeen, letterSeen = 1; 当right = 2,window['b'-'A'] = 1 <= letter['b'-'A'], letterSeen = 2 == T.length, "aab"是第一个符合条件的窗口;再固定右边活动左边来找是不是还有更小的,window['a'-'A'] = 1, letterSeen == T.length, "ab"符合条件; 继续右滑,window['a'-'A'] = 0 < T['a' - 'A'], letterSeen = 1 不符合条件。
++letterSeen if window[c-'A'] <= T[c-'A']
Note.
window[c-'A']用作字母为key的map很方便
滑动左边不要忘记 ++left
class Solution {
public String minWindow(String s, String t) {
int[] letterT = new int[256];
for(int i = 0; i < t.length(); ++i) {
++letterT[t.charAt(i) - 'A'];
} int[] window = new int[256];
int start = -1;
int letterSeen = 0;
int minLen = Integer.MAX_VALUE;
for(int left = 0, right = 0; right < s.length(); ++right) {
int keyRight = s.charAt(right) - 'A';
++window[keyRight];
if(window[keyRight] <= letterT[keyRight]) {
++letterSeen;
while(letterSeen == t.length()) {
if(right - left + 1 < minLen) {
minLen = right - left + 1;
start = left;
}
int keyLeft = s.charAt(left) - 'A';
--window[keyLeft];
if(window[keyLeft] < letterT[keyLeft]) {
--letterSeen;
}
++left;
}
}
} if(start == -1) {
return "";
}
return s.substring(start, start + minLen);
}
}
python
class Solution:
def minWindow(self, s: str, t: str) -> str:
letterT = collections.Counter(t) window = collections.defaultdict(int)
left = 0
letterSeen = 0
start = -1
minLen = len(s) + 1
for right in range(len(s)): window[s[right]] += 1
if window[s[right]] <= letterT[s[right]]:
letterSeen += 1
while letterSeen == len(t):
if right - left + 1 < minLen:
start = left;
minLen = right - left + 1 window[s[left]] -= 1
if window[s[left]] < letterT[s[left]]:
letterSeen -= 1 left += 1 if start == -1:
return "" return s[start: start + minLen]
2.b 只需要一个map letterT, 用右滑动来减字母个数,左滑动来加字母个数,如果左边也扫到尾部,正好左右抵消还原原来的map.
class Solution {
public String minWindow(String s, String t) {
int[] letterT = new int[256]; for(int i = 0; i < t.length(); ++i) {
++letterT[t.charAt(i) - 'A'];
} int lettersSeen = 0;
int minLen = Integer.MAX_VALUE;
int start = -1;
for(int left = 0, right = 0; right < s.length(); ++right) {
--letterT[s.charAt(right) - 'A'];
if(letterT[s.charAt(right) - 'A'] >= 0) {
++lettersSeen; while(lettersSeen == t.length()) {
if(right - left + 1 < minLen) {
minLen = right - left + 1;
start = left;
}
++letterT[s.charAt(left) - 'A'];
if(letterT[s.charAt(left) - 'A'] > 0) {
--lettersSeen;
}
++left;
}
}
} if(start == -1) {
return "";
}
return s.substring(start, start + minLen);
}
}
python:
class Solution:
def minWindow(self, s: str, t: str) -> str:
letterT = collections.Counter(t) lettersSeen = 0
start = -1
minLen = len(s) + 1
left = 0
for right in range(len(s)):
if s[right] in letterT:
letterT[s[right]] -= 1
if letterT[s[right]] >= 0:
lettersSeen += 1 while lettersSeen == len(t):
if right - left + 1 < minLen:
minLen = right - left + 1
start = left if s[left] in letterT:
letterT[s[left]] += 1 if letterT[s[left]] > 0:
lettersSeen -= 1 left += 1 if start == -1:
return "" return s[start: start+minLen]
Minimum Window Substring LT76的更多相关文章
- 53. Minimum Window Substring
Minimum Window Substring Given a string S and a string T, find the minimum window in S which will co ...
- Minimum Window Substring @LeetCode
不好做的一道题,发现String Algorithm可以出很多很难的题,特别是多指针,DP,数学推导的题.参考了许多资料: http://leetcode.com/2010/11/finding-mi ...
- LeetCode解题报告—— Minimum Window Substring && Largest Rectangle in Histogram
1. Minimum Window Substring Given a string S and a string T, find the minimum window in S which will ...
- leetcode76. Minimum Window Substring
leetcode76. Minimum Window Substring 题意: 给定字符串S和字符串T,找到S中的最小窗口,其中将包含复杂度O(n)中T中的所有字符. 例如, S ="AD ...
- 【LeetCode】76. Minimum Window Substring
Minimum Window Substring Given a string S and a string T, find the minimum window in S which will co ...
- 刷题76. Minimum Window Substring
一.题目说明 题目76. Minimum Window Substring,求字符串S中最小连续字符串,包括字符串T中的所有字符,复杂度要求是O(n).难度是Hard! 二.我的解答 先说我的思路: ...
- [LeetCode] Minimum Window Substring 最小窗口子串
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
- [Leetcode][JAVA] Minimum Window Substring
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
- Java for LeetCode 076 Minimum Window Substring
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
随机推荐
- CSS Media Query
[CSS Media Query] CSS Media Queries are a feature in CSS3 which allows you to specify when certain C ...
- DIV实现垂直居中的几种方法
说道垂直居中,我们首先想到的是vertical-align属性,但是许多时候该属性并不起作用.例如,下面的样式并不能达到内容垂直居中显示 div { width:200px; height:300px ...
- zookeeper报错: org.I0Itec.zkclient.exception.ZkMarshallingError: java.io.EOFException
zookeeper报错: org.I0Itec.zkclient.exception.ZkMarshallingError: java.io.EOFException 主要因为是没有序列化. 可以使用 ...
- vue confirm确认
this.$confirm('您确定删除吗?').then(_ => { do something ... (确认) }).catch(_ => { do something ... (取 ...
- 第九章 词典 (e)桶/计数排序
- openstack(Pike 版)集群部署(八)--- 连接Ceph Cluster 作为后端存储
一.openstack Glance + ceph Cluster 部署: 博客:http://www.cnblogs.com/weijie0717/p/8563294.html 参考 续 部分. ...
- JavaWeb网站后台开发记录手册
1.javaweb网站后台开发 1.封装DBTools类 1.注册数据库驱动 Class.forName("oracle.jdbc.driver.OracleDriver"); 2 ...
- POJ-3984.迷宫问题(BFS + 路径输出)
昨天中午做的这道题,结果蛙了一整天,就因为一行代码困住了,今天算是见识到自己有多菜了.流泪.jpg 本题大意:给一个5 * 5的迷宫,1表示墙壁,0表示通路,从左上角走到右下角并输出路径. 本题思路: ...
- PHPlaravel中从数据库中选择数据是增加时间条件及各种条件
注:附加条件后要加get函数. 1.public function getForDataTable($startTime,$endTime){ return $this->query() -&g ...
- JavaScript各种继承方式(五):寄生式继承(parasitic)
一 原理 与原型式继承完全相同,只是对父类的实例(也当作子类的实例使用)进行了增强. function create(obj){ let mango = Object.create(obj); man ...