[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.
题意:在S中寻找最小包含T的子串,不管字母顺序。
思路:采用桶排序。先将T中所有的元素放入hash表中,然后遍历字符串S。如果当前字符在hash表中没有,说明这个不在T中,则直接跳过。若在,则将hash表中对应的字符的个数减1,说明T中的字符已经找到一个了;此时,若对应字符的个数不小于0,说明这个字符是有效的。什么意思了?如:字符串S=“ABAC”找T=“AC”,第一次,找到“A”时,hash表中A对应的个数变为0,即为有效的A,计数器count记下了A的个数;再次遇到A时,说明T只有一个A,且已经被记下了,所以不需要再次计数。即,忽略重复的,找到T中全部的就行。那明明是第二个A更符合题意,为什么要记下第一个A,这个会在后面慢慢的说明。
这样直到T的中的每个字符都被记下了,且只记下一次。这时,我们更新最小的合乎题意的子字符串的长度。这时,我们遇到一个问题,就是,如果开始时,有很多字符不是T中的,但是我们记下的最小字符串包括这些,怎么办?我们只需不断的将左指针向右移动,直到遇到第一个在T中的字符,这个过程中,我们不断的更新minlen长度,这样我们就得到了这次的复合题意的最下子字符串的长度。
那么我们如何得到下一个符合题意的长度?此时,我们只需将最左端字符在hash表中的个数加1,然后count减1,就实现了,重新寻找下一个子字符串的循环。因为,会遍历完S,所以之前说的遇到第二个A时,会重新更新minlen,所以之前只用记住一个A的。参考了Grandyang的博客。代码如下:
class Solution {
public:
string minWindow(string S, string T)
{
if(T.size()>S.size()) return "";
string res="";
int left=,count=,minLen=S.size()+;
unordered_map<char,int> m;
for(int i=;i<T.size();++i)
{
if(m.find(T[i]) !=m.end())
++m[T[i]];
else
m[T[i]]=;
}
for(int right=;right<S.size();++right)
{
if(m.find(S[right]) !=m.end())
{
--m[S[right]];
if(m[S[right]]>=)
++count;
while(count==T.size())
{
if(right-left+<minLen)
{
minLen=right-left+;
res=S.substr(left,minLen);
}
if(m.find(S[left]) !=m.end())
{
++m[S[left]];
if(m[S[left]]>)
--count;
}
left++;
}
}
}
return res;
}
};
解题思路:其实就是通过双指针维持一个Window,窗口右指针向右扩张用来找到包含子串为目的,窗口左指针向右收缩以使子串最小。典型的滑动窗口方法的实现。
也可以用数组来替代hash表,参考 曲高和寡_健的博客,代码如下:
class Solution {
public:
string minWindow(string S, string T)
{
int sLen=S.size(),tLen=T.size();
if(sLen==||tLen==)
return "";
vector<int> sHash(,),tHash(,);
for(int i=,i<tLen;++i)
{
tHash[T[i]]++;
}
int beg=-,end=sLen,count=,minLen=sLen;
for(int i=,start=i;i<sLen;++i)
{
++sHash[S[i]];
if(sHash[S[i]]<=tHash[S[i]])
++count;
if(count==tLen)
{
while(start<i&&sHash[S[start]]>tHash[S[start]])
{
--sHash[S[start]];
start++;
}
if(i-start<minLen)
{
minLen=i-start;
beg=start;
end=i;
}
--sHash[S[start++]]; //寻找下一个符合要求的子字符串
--count;
}
}
if(beg==-)
return "";
return S.substr(beg,end-beg+);
}
};
这种方法看的更为清晰些。
[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 ...
- [leetcode]76. Minimum Window Substring最小字符串窗口
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
- 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] 76. Minimum Window Substring 最小窗口子串
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
- [LeetCode] Minimum Window Subsequence 最小窗口序列
Given strings S and T, find the minimum (contiguous) substring W of S, so that T is a subsequence of ...
- [leetcode]Minimum Window Substring @ Python
原题地址:https://oj.leetcode.com/problems/minimum-window-substring/ 题意: Given a string S and a string T, ...
- [LeetCode] Minimum Window Substring 散列映射问题
题目: Given a string S and a string T, find the minimum window in S which will contain all the charact ...
- lintcode 中等题:minimum window substring 最小子串覆盖
题目 最小子串覆盖 给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串. 样例 给出source = "ADOBECODEBANC ...
- LeetCode()Minimum Window Substring 超时,但觉得很清晰。
我的超时思路,感觉自己上了一个新的台阶,虽然超时了,但起码是给出了一个方法. 遍历s 一遍即可,两个指针,当找到了一个合格的字串后,start 开始走,直到遇到s[start]在t中 如果不符合,en ...
随机推荐
- gitlab改root密码
1. ~$ sudo gitlab-rails console production 2.查询要改的用户 irb(main)::> u = User.where().first => #& ...
- 吴裕雄 python 机器学习——层次聚类AgglomerativeClustering模型
import numpy as np import matplotlib.pyplot as plt from sklearn import cluster from sklearn.metrics ...
- 第十五届北京师范大学程序设计竞赛现场决赛题解&源码(A.思维,C,模拟,水,坑,E,几何,思维,K,字符串处理)
#include <bits/stdc++.h> using namespace std; int main() { int T,n,a,b; while(cin>>T) { ...
- 【quick-cocos2d-lua】 基本类及用法
1.cc.Director(导演类) 获得导演类实例:local director = cc.Director : getInstance() 其中 cc 是Cocos2d-x Lua 类的命名空间 ...
- NGUI组件整理总结
一图流: 注意: private void RClickUI(Vector3 newPos) { this.gameObject.SetActive(true); this.transform.loc ...
- Python 作用域和命名空间
在介绍类之前,我首先要告诉你一些Python的作用域规则.类定义对命名空间有一些巧妙的技巧,你需要知道作用域和命名空间如何工作才能完全理解正在发生的事情.顺便说一下,关于这个主题的知识对任何高级Pyt ...
- [CF106C]Buns
面包师Lavrenty打算用馅料做几个面包,然后把它们卖掉. Lavrenty有\(n\)克面团和\(m\)种不同的馅料.馅料种类的下标从\(1到m\),他知道他的第\(i\)种馅料剩下\(a_i\) ...
- 什么是Spark
什么是Spark Apache Spark是一个开源集群运算框架, 相对于Hadoop的MapReduce会在运行完工作后将中介数据存放到磁盘中,Spark使用了存储器内运算技术,能在数据尚未写入硬盘 ...
- 01背包问题:DP
题目描述: 有 N 件物品和一个容量是 V 的背包.每件物品只能使用一次. 第 i 件物品的体积是 vi,价值是 wi. 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大.输出 ...
- 如何在etherscan提交代币官方信息
https://ethlinkersupport.zendesk.com/hc/zh-cn/articles/360001334992-%E5%A6%82%E4%BD%95%E5%9C%A8ether ...