题目:

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的更多相关文章

  1. 【Sliding Window】单调队列

    题目描述 给你一个长度为 N 的数组,一个长为 K 的滑动的窗体从最左移至最右端,你只能见到窗口的 K 个整数,每次窗体向右移动一位,如下表:

  2. hdu 4739【位运算】.cpp

    题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...

  3. 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~ ...

  4. 【Edit Distance】cpp

    题目: Given two words word1 and word2, find the minimum number of steps required to convert word1 to w ...

  5. 【Valid Sudoku】cpp

    题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...

  6. 【Permutations II】cpp

    题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...

  7. 【Subsets II】cpp

    题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...

  8. 【Sort Colors】cpp

    题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...

  9. 【Sort List】cpp

    题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...

随机推荐

  1. Selenium入门7 内嵌框架iframe

    如果网页内嵌iframe,那么iframe里的元素是无法直接定位的,需要使用switch_to.frame进入frame操作: 之后需要再操作页面上非嵌入在iframe里的元素,需要使用switch_ ...

  2. andriod给ListView中的TextView增加跑马灯效果

    正常情况下跑马灯效果只需要在TextView中添加android:ellipsize="marquee" android:singleLine="true" a ...

  3. 1.6 NBU Catalog备份还原

    用户的数据保存到了磁盘或者磁带中,并且是安全的,NBU所在的机器还有可能发生故障,需要重新安装或者将NBU部署到其他的机器中继续使用. 在这种情况下,如何让NBU知道用户已经存在的备份策略和存储单元配 ...

  4. C/C++语言代码规范

    1.标识符名称: 标识符名称包括函数名.常量名.变量名等.这些名字应该能反映它所代表的实际东西,具有一定的意义,使其能 够见名知义,有助于对程序功能的理解.规则如下: 所有宏定义.枚举常数和const ...

  5. jdk8环境变量 jdk8图解安装 java8安装

    JDK8 是JDK的最新版本,加入了很多新特性,如果我们要使用,需要下载安装: JDK8在windows xp下安装有点问题,所以在WIN7下安装 WIN7操作系统有32位和64位,分别要下载对应的J ...

  6. CDH4.5.0下安装snappy

    编译源代码 http://www.cnblogs.com/chengxin1982/p/3862289.html 测试参考 http://blog.jeoygin.org/2012/03/java-c ...

  7. element el-tooltip 内容换行的方法

    <el-tooltip class="item" effect="light" placement="top-start">  ...

  8. 微信小程序清除默认样式

    1.清除button的默认样式 button::after{border:none;}input{outline:none;border:none;list-style: none;}

  9. linux 基本命令笔记

    nohup [process]  & 后台挂起命令nohup 挂起& 后台运行 python3 manage.py runserver 0.0.0.0:8080 python -r 递 ...

  10. get请求中文乱码问题

    Get中文乱码解决 Get请求类型: <form action="${pageContext.request.contextPath}/addArtical.action"  ...