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 ...
随机推荐
- 1.5、CDH 搭建Hadoop在安装之前(定制安装解决方案)
Cloudera托管两种类型的软件存储库,您可以使用它们来安装诸如Cloudera Manager或CDH-parcel存储库和软件包存储库之类的产品. 在大多数情况下,这些存储库是有效的解决方案,但 ...
- OpenSessionInViewFilter 的配置及作用(原文地址: http://blog.csdn.net/sunsea08/article/details/4545186)
spring为我们解决hibernate的Session的关闭与开启问题. Hibernate 允许对关联对象.属性进行延迟加载,但是必须保证延迟加载的操作限于同一个 Hibernate Sessio ...
- cdh5.13.1 hadoop hdfs HA模式无法启动
经过观察日志发现,JN三个节点启动正常,只有NN节点启动时提示JN节点没有格式化 停止HDFS下面所有服务 先启动JN节点 然后启动一个NN节点,观察三个JN节点日志 发现其中一个节点的日志正常,没有 ...
- openstack(Pike 版)集群部署(二)--- Keystone 部署
一.介绍 参照官网部署:https://docs.openstack.org/keystone/queens/install/ 继续上一博客进行部署:http://www.cnblogs.com/we ...
- c++三种进制格式
来源:c++ primer plus 常用的进制有二进制,八进制,十进制,十六进制,在c++的头文件iostream里除了提供了endl控制符之外,还提供了控制进制的控制符,(不含二进制),分别是八进 ...
- 【资料整理】ADO.NET
ADO.NET: 1.SYSTEM.DATA 命名空间下类的集合的统称,用于操作 连接数据库的 它提供了统一的编程接口,可以操作不同的数据库 数据库实例:默认实例(MSSQLSEVER)和命名实例(M ...
- express 学习札记
Enjoy yourself! 祝你玩得开心! I have no idea. 我没有头绪. I just made it! 我做到了! I’ll see to it 我会留意的. Express ...
- require模块化载入
1,模块化require的载入步骤 1,一个总文件夹,,里面三个子文件夹 ,, 分别是 2,common 里面是放一些公共方法和自己封装的方法 js里面是放自己的业务逻辑js文件和一些模块化的 ...
- js五种继承优缺点
//1.原型继承 //缺点: 当父级的属性有引用类型的时候,任意一个实例修改了这个属性,其他实例都会受影响 // 1)基本类型:Number Boolean String undefined null ...
- 将之前的Power idea公司的数据按照下图所示的格式在屏幕上显示出来。
之前的文章 示例代码如下 assume cs:codesg ;将整个data段看作是一个数组,长度一共为 ;21*4+21*4+2*21=168+42=210字节 data segment db ' ...