题目:

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. IOS Git源代码管理工具

    .新建一个“本地仓库” $ git init .配置仓库 >告诉git你是谁 git config user.name lnj >告诉git怎么联系你 git config user.em ...

  2. EF 连接数据库 Mysql (database first ) 一个表对应一个模型

    准备工作 1.下载vs2015 2.下载mysql2017 3.安装 1.创建数据库 2. 将数据库映射成模型 3创建aspx 文件. 写下窗体内容的代码 hello_worldEntities en ...

  3. powerdesigner15 反向工程

  4. jQuery性能优化和技巧

    jQuery性能优化 ①使用最新版本的jQuery类库 ②使用合适的选择器 ③缓存对象 ④循环时的DOM操作 ⑤数组方式使用jQuery对象 ⑥事件代理 ⑦将你的代码转化成jQuery插件 ⑧使用jo ...

  5. 协议:Http Https TCP/IP

    Http协议 1.1 Http概述 HTTP(hypertext transport protocol),即超文本传输协议.这个协议详细规定了浏览器和万维网服务器之间互相通信的规则.HTTP就是一个通 ...

  6. 破解weblogic(数据库)密码

    破解weblogic(数据库)密码所需步骤 注意:本例子本人以本地weblogic为列,必须已经安装weblogic 1.需要问题件 1>.数据源配置文件HKS***-****-jdbc.xml ...

  7. forEach、for...in、for...of

    forEach 数组实例的遍历方法 const arr=['red', 'green', 'blue']; arr.forEach(function(element, index) { console ...

  8. Oracle中文乱码解决

    查看当前Oracle字符集 select userenv('language') from dual; USERENV('LANGUAGE') ---------------------------- ...

  9. Mysql查看锁等信息SQL语句

    查看锁等信息,包括锁信息: select "HOLD:",ph.id h_processid,trh.trx_id h_trx_id,trh.trx_started h_start ...

  10. mysql基础 反范式化