【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 ...
随机推荐
- UOJ #207. 共价大爷游长沙
#207. 共价大爷游长沙 链接:http://uoj.ac/problem/207 题意:给一棵树,要求支持加边.删边.询问一条边是否被所有路径覆盖.同时路径端点集合有加入与删除操作. 想法: 考虑 ...
- HTML入门1—HTML基础学习
html文档结构 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...
- dd-wrt ddns更新失败由于电信提供的ip不是公网ip
由于电信提供的ip地址原来是公网的ip,后来电信通过nat提供一个内网ip,导致ddns更新失败.电话给电信客服10000号,让他们修改回来之后就可以了. 如果ddns更新失败,尤其是原本是正常的,后 ...
- 2017.10.26 JavaWeb----第五章 JavaBean技术
JavaWeb----第五章 JavaBean技术 (1)JavaBean技术 JavaBean技术是javaweb程序的重要组成部分,是一个可重复使用的软件组件,是用Java语言编写的.遵循一定的标 ...
- 使用QT开发GoogleMap瓦片显示和下载工具(1)——QT开发环境准备
由于是第一次使用qt,光是QT的安装和调试就费了好大功夫,汗一个,下面记录下过程和遇到的问题的解决方法吧. 下载QT 直接Google搜索“QT”,进入官网http://qt-project.org/ ...
- C# 复合赋值操作符
前面讲过如何使用算术操作符来创建新值.例如,以下语句使用操作符+来创建比变量answer大42的一个值,新值将写入控制台: Console.WriteLine(answer + 42); 前面还讲过如 ...
- JAVA_Converter_字符串类型转Date类型
我们知道数据库中的时间一般为Date类型,而前台传递过来的为字符串,BeanUtils在封装数据的时候,没有将类型转换,导致报异常... 我们只需要在封装数据之前,使用自定义转换器即可: 代码如下: ...
- jquery-ui-custom autocomplete
//jsp <%@ page language="java" import="java.util.*" pageEncoding="utf-8& ...
- 关于var和ES6中的let,const的理解
var的作用就不多说了,下面说说var的缺点: 1.var可以重复声明 var a = 1; var a = 5; console.log(a); //5 不会报错 在像这些这些严谨的语言来说,一般是 ...
- 利用bootstrap制作滚动监听
滚动监听(Scrollspy)插件,即自动更新导航插件,会根据滚动条的位置自动更新对应的导航目标. 在这里,需要引入三个文件:bootstrap.min.css jquery-3.3.1.j ...