LeetCode——727.Minimum Window Subsequence
一.题目链接:https://leetcode.com/problems/minimum-window-substring/
二.题目大意:
给定两个字符串S和T,要求从S中找出包含T中所有字母的最短子串,同时要求时间复杂度为O(n)。
三.题解:
这道看上去和https://leetcode.com/problems/longest-substring-without-repeating-characters最长不重复子序列类似,似乎都可以利用滑窗法来解决(当然,此处的窗口大小必然是动态的,不固定的)。然而不同的是,S中的字符可能包含T中不存在的字符,也就是说:在滑窗构建的过程中(遍历S的过程中),会遇到两种情况,当前字符不是T中的字符和当前字符是T中的字符。那么如何构建滑窗呢?具体如下:
(1)我们设置两个指针left和right,分别表示滑窗的两端。哈希表_map用于存储T中出现的字符以及相应的个数。cnt用于统计目前滑窗中出现的T中的字符的个数。
(2)right指针不停的向右移动,并且判断此处的字符是否是T中的字符,是的话,计数器cnt加1,同时_map中相应的字符对应的次数减去1。当cnt的数值与T的长度相同时,表示我们已经构造完成了一个符合条件的滑窗了。
(3)由于,整个S中可能存在多个符合条件的滑窗,所以当我们找到一个符合条件的滑窗时,需要记录相应的长度和起始下标;然后再去构建下一个滑窗。
(4)如何构建下一个滑窗呢?此时,就需要操作左指针left了,将left向右移动,若left处的字符是T中的字符的话,则cnt减去1。相应的_map处的字符对应的次数加1,此时需要构建新的滑窗,再去操作right指针;重复这个过程直至遍历完S。如果left处的字符不是T中的字符的话,继续右移,知道遇到T中的字符。
实现代码如下:
class Solution {
public:
string minWindow(string S, string T) {
int s_len = S.size();
int t_len = T.size();
if(s_len == 0 || t_len == 0 || s_len < t_len)//特殊输入的处理
return "";
int cnt = 0;//用于统计当前滑动窗口内中包含T中的字符的个数
int len = INT_MAX;//此处我用的int的最小值,也可以用s_len + 1
int head = -1;//记录最终结果的初始位置
int left = 0, right = 0;//定义滑动窗口的两个边界
unordered_map<char,int> _map;//存储T中的字符及出现的次数
for(int i = 0; i < t_len; i++)//初始化哈希表_map
{
if(_map.find(T[i]) == _map.end())
_map.insert(pair<char,int>(T[i],1));
else
(_map.find(T[i])->second)++;
}
for(right = 0 ; right < s_len; right++)//移动右指针
{
if(_map.find(S[right]) != _map.end())//当窗口内部含有T中的字符时
{
_map[S[right]]--;//相应字符的此处减1
if(_map[S[right]] >= 0)//减1后如果次数大于等于0,说明我们已经满足一个字符了,所以cnt加1
cnt++;
while(cnt == t_len)//如果滑窗内已经包含所有T中的字符
{
if(right - left + 1 < len)//更新最小的情况
{
len = right - left + 1;
head = left;
}
if(_map.find(S[left]) != _map.end())//如果左指针处指的是T中的字符;如果不是T中的字符则继续左移
{
_map[S[left]]++;//相应处的字符的次数加1
if(_map[S[left]] > 0)//如果加1之后此处大于0了,说明需要这个字符(这个字符是唯一的),如果向右移动的话(舍去这个字符),cnt就会减1
cnt--;
//如果这个字符不是唯一的话,不需要操作
}
left++;//移动左指针,直到滑窗中不再包含T中的全部字符
}
}
}
return head == - 1 ?"" : S.substr(head,len);//head== -1相当于没找到符合条件的子序列
}
};
实际上,左指针移动时,相当于考虑了三种情况:left处的字符不是T中的字符、left处的字符是T中的字符且是唯一的、left处的字符是T中的字符但不是唯一的(滑窗中其他处还有这个字符,此时_map[S[left]]是小于等于0的)。
我们也可以把_map[S[i]]理解成还需要多少个S[i]字符。该算法的时间复杂度为O(N),空间复杂度为O(1),因为ASCII码的话,最多256个字符就行。
LeetCode——727.Minimum Window Subsequence的更多相关文章
- [LeetCode] 727. Minimum Window Subsequence 最小窗口序列
Given strings S and T, find the minimum (contiguous) substring W of S, so that T is a subsequence of ...
- [LeetCode] 727. Minimum Window Subsequence 最小窗口子序列
Given strings S and T, find the minimum (contiguous) substring W of S, so that T is a subsequenceof ...
- LC 727. Minimum Window Subsequence 【lock,hard】
Given strings S and T, find the minimum (contiguous) substring W of S, so that T is a subsequenceof ...
- [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] 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] 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][JAVA] 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 (hard) ★
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 ...
随机推荐
- windows service 2008 R2 安装net4.6环境失败,windows service 2008 R2 升级sp1问题
一.错误 1.因为我的程序是以vs2017开发的,在windows service 2008 R2 IIS部署项目文件报出错误,因此要安装net4.6的环境. 2.windows service 2 ...
- JavaScript基础二
1.7 常用内置对象 所谓内置对象就是ECMAScript提供出来的一些对象,我们知道对象都是有相应的属性和方法 1.7.1 数组Array 1.数组的创建方式 字面量方式创建(推荐大家使用这种方式, ...
- openLDAP安装时无法操作根节点数据,提示的是This base cannot be created with PLA.
1.无法操作根节点数据,提示的是This base cannot be created with PLA. 解决办法 1)添加一个base.ldif文件,里面的dc和配置文件里的保持一致即可 dn: ...
- 精析python中的装饰器、生成器
装饰器: 在编程时,要遵循一个原则,就是开放-封闭原则. 在不破坏原函数的情况下,要想对原函数进行一些修饰,那么这里就要用到装饰器. 例如:你完成了一些用函数写成的项目,此时公司正在年度考核,你需要给 ...
- ECharts4简单入门
参考:echarts3 使用总结 echarts3使用总结2 最近在leader的忽悠下开始接触echarts,的确被它丰富的图表样式吸引了,现写入门教程如下: 官方入门教程参考: EChart ...
- redis基础学习总结
学习目标: 1.redis特点及安装 2.redis键值操作 3.redis数据类型[string, link,set,orderset,hash] 4.事务 5.消息 ...
- 201621123075 Week03-面向对象入门
1.本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识点组织起来.请使用工具画出本周学习到的知识点及知识点之间的联系.步骤如下: 1.1 写出你认 ...
- Spring mvc初学
转自:http://www.cnblogs.com/bigdataZJ/p/springmvc1.html 从今天起,准备好好审视并学习Spring mvc. 虽然从学java的第一个程序——hell ...
- 运维自动化 第一章 git
一.git简单操作 4个地方: 工作区: 当前编辑的区域 缓存区: add 之后的区域 本地仓库: commit之后的区域 远程仓库 :远程的区域 简单操作: git init 初始化操作 比如我选定 ...
- jq demo 简单的图片懒加载效果
重点:在元素进入可视区域后,把图片元素的 _src 的值,赋值给 src <!DOCTYPE HTML> <html> <head> <meta http-e ...