【Minimum Window】cpp
题目:
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.
代码:
class Solution {
public:
string minWindow(string s, string t) {
if (s.empty() && t.empty() ) return "";
if (s.size()<t.size()) return "";
const int ASCII_MAX = ;
// record how much times a char occurs in t
int t_char_count[ASCII_MAX] = {};
for ( int i=; i<t.size(); ++i ) { t_char_count[(int)t[i]]++; }
// record how much times a char occurs in s
int s_char_count[ASCII_MAX] = {};
// global min begin and end index for minimum interval
int begin_min=-, end_min=s.size();
// local min begin ( no need to record local min end ,because it is 'i' )
int begin = ;
int match_size = ;
for ( int i=; i<s.size(); ++i )
{
// current interval not match && current char in t
if ( t_char_count[(int)s[i]]> )
{
//cout << s[i] << ":" << t_char_count[s[i]] << endl;
s_char_count[(int)s[i]]++;
// if a char occurs more times in current interval s than in t, can not increase match_size
if ( s_char_count[(int)s[i]]<=t_char_count[(int)s[i]] ) match_size++;
}
if ( match_size==t.size() )
{
// move begin forward untill not match
while ( begin<=i )
{
// only address chars not in t
if ( s_char_count[(int)s[begin]]> )
{
if ( s_char_count[(int)s[begin]]-<t_char_count[(int)s[begin]] )
{
//cout << s_char_count[s[begin]] << endl;
match_size--;
break;
}
s_char_count[(int)s[begin]]--;
}
begin++;
}
s_char_count[(int)s[begin]]--;
// update global min begin and end
if ( end_min-begin_min > i-begin ) { end_min = i; begin_min = begin; }
begin++;
}
}
if( end_min-begin_min>s.size() ) return "";
return s.substr(begin_min,end_min-begin_min+);
}
};
tips:
曾经以为这种题比较简答,实际上不带算法模板套路的题才是最费神的。
这道题一开始的思路是记录t中每个字符最左边到哪最右边到哪,然后再云云;这个想法不太靠谱。
如果是bruce force暴力解法,时间复杂度可以是O(n²)的:
1. 遍历每个位置,以每个位置为中心,往左右走,直到包含所有的元素,取最短的。
2. 取所有interval中最短的。
可以AC的解法思路如下:
1. 维护几个核心变量:
a)t中每个字符出现了几次(t_char_count)
b) s中当前区间里面,t中每个字符出现了几次(s_char_count)
c) s当前区间是否满足包含t(match_size)
2. 这道题思路很有趣:先找满足包含t的区间;一旦找到了这样的区间,再缩小这样的区间。
缩减区间的方法:后面的指针保持不动,前面的指针往后移动,直到match_size < t.size(),则证明当前区间已经是最小的满足条件的区间了。
3. 动态更新最小区间。
主要参考:
http://www.cnblogs.com/TenosDoIt/p/3461301.html
http://fisherlei.blogspot.sg/2012/12/leetcode-minimum-window-substring.html
============================================
第二次过这道题,静下心来码。
class Solution {
public:
string minWindow(string s, string t) {
int t_counts[] = {};
int s_counts[] = {};
for ( int i=; i<t.size(); ++i ) t_counts[(int)t[i]]++;
int matchTime = ;
int begin = -;
int end = s.size();
int b = ;
for ( int i=; i<s.size(); ++i )
{
// only address character occurs in string t
if ( t_counts[(int)s[i]]> )
{
s_counts[(int)s[i]]++;
// after s_count add one change matchTime
if ( s_counts[(int)s[i]]<=t_counts[(int)s[i]] ) matchTime++;
}
// when there is a window, then minimisze it
if ( matchTime==t.size() )
{
while ( b<=i )
{
// only address charatcers occurs in string t
if ( s_counts[(int)s[b]]> )
{
// if move over 'begin then 'can not keep window
if ( s_counts[(int)s[b]]- < t_counts[(int)s[b]] )
{
matchTime--;
break;
}
s_counts[(int)s[b]]--;
}
b++;
}
if ( i-b < end-begin )
{
begin = b;
end = i;
}
s_counts[(int)s[b]]--;
b++;
}
}
if ( end-begin>s.size() ) return "";
return s.substr(begin, end-begin+);
}
};
【Minimum Window】cpp的更多相关文章
- 【Sliding Window】单调队列
题目描述 给你一个长度为 N 的数组,一个长为 K 的滑动的窗体从最左移至最右端,你只能见到窗口的 K 个整数,每次窗体向右移动一位,如下表:
- hdu 4739【位运算】.cpp
题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...
- Hdu 4734 【数位DP】.cpp
题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...
- 【Edit Distance】cpp
题目: Given two words word1 and word2, find the minimum number of steps required to convert word1 to w ...
- 【Valid Sudoku】cpp
题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...
- 【Permutations II】cpp
题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...
- 【Subsets II】cpp
题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...
- 【Sort Colors】cpp
题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...
- 【Sort List】cpp
题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...
随机推荐
- Selenium入门7 内嵌框架iframe
如果网页内嵌iframe,那么iframe里的元素是无法直接定位的,需要使用switch_to.frame进入frame操作: 之后需要再操作页面上非嵌入在iframe里的元素,需要使用switch_ ...
- andriod给ListView中的TextView增加跑马灯效果
正常情况下跑马灯效果只需要在TextView中添加android:ellipsize="marquee" android:singleLine="true" a ...
- 1.6 NBU Catalog备份还原
用户的数据保存到了磁盘或者磁带中,并且是安全的,NBU所在的机器还有可能发生故障,需要重新安装或者将NBU部署到其他的机器中继续使用. 在这种情况下,如何让NBU知道用户已经存在的备份策略和存储单元配 ...
- C/C++语言代码规范
1.标识符名称: 标识符名称包括函数名.常量名.变量名等.这些名字应该能反映它所代表的实际东西,具有一定的意义,使其能 够见名知义,有助于对程序功能的理解.规则如下: 所有宏定义.枚举常数和const ...
- jdk8环境变量 jdk8图解安装 java8安装
JDK8 是JDK的最新版本,加入了很多新特性,如果我们要使用,需要下载安装: JDK8在windows xp下安装有点问题,所以在WIN7下安装 WIN7操作系统有32位和64位,分别要下载对应的J ...
- CDH4.5.0下安装snappy
编译源代码 http://www.cnblogs.com/chengxin1982/p/3862289.html 测试参考 http://blog.jeoygin.org/2012/03/java-c ...
- element el-tooltip 内容换行的方法
<el-tooltip class="item" effect="light" placement="top-start"> ...
- 微信小程序清除默认样式
1.清除button的默认样式 button::after{border:none;}input{outline:none;border:none;list-style: none;}
- linux 基本命令笔记
nohup [process] & 后台挂起命令nohup 挂起& 后台运行 python3 manage.py runserver 0.0.0.0:8080 python -r 递 ...
- get请求中文乱码问题
Get中文乱码解决 Get请求类型: <form action="${pageContext.request.contextPath}/addArtical.action" ...