您的位置:首页 > 其它

最小窗口子字符串 LEETCODE 探索提升遇到的第一个困难的题目。

2018-08-05 13:27 141 查看

最小窗口子字符串

给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。

示例:

[code]输入: S = "ADOBECODEBANC", T = "ABC"
输出: "BANC"

说明:

  • 如果 S 中不存这样的子串,则返回空字符串 
    ""
  • 如果 S 中存在这样的子串,我们保证它是唯一的答案

原题地址

问题已经很具体了,分析ac代码。

[code]class Solution {
public:
string minWindow(string s, string t) {
vector<int> map(128,0);
for(auto c: t) map[c]++;
int counter = t.size(), begin = 0, end = 0, d = INT_MAX, head = 0;
while(end<s.size()){
if(map[s[end++]]-- > 0) counter--; //in t
while(counter == 0){ //valid
if(end - begin < d)  d = end - (head = begin);
if(map[s[begin++]]++ == 0) counter++;  //make it invalid
}
}
return d==INT_MAX? "":s.substr(head, d);
}
};

定义ascII 128 字符hash 是在字符串处理中,检测是否出现过的常用做法。 

通过第一行第二行代码确定了需要包含的字符范围;我最初的想法是建立一个unorder_map 实质是一样的。 

对于字符串处理这种方法更经济直观。 

对于截取子串来说。 在 counter 等于零的时候 , 

end  到 begin 一定是一条包含子串,这个时候 需要判断是否是最短的子串。 

长度就等 end - begin。先记录下来。 然后在改变原先的map 现在需要的是继续搜索下一串子串,头指针前移hash自加。但是问题是这样不就不知道子串是不是包含t 了么。依然是知道的。注意看if(map[s[end++]]-- > 0) counter--; //in t 这个代码。在这里map中原来为1的变成了零,但是原来没有的字符变成的是-1;在哈希中就实现了不包含的字符串就跳过了。当等于零的点在后一个循环中又出现时,说明包含的字符出现了,那么给他自加到1,而没有包含的字符从-1自加到零。counter 在自加1。跳出内层循环。同时相当于扔掉最早的出现的一个包含字符。尾部继续搜索最先出现的这个字符。

整个算法拆开来就是这样。 其中关键的有几点 

主循环只走一遍,end 在循环内无脑自加,同时利用hash检测是否包含。同时又标记是否遍历过。 记录当前查找进度

内层循环 主要功能 第一记录当前找到的字符串长度,与位置。第二,丢掉最先找到的包含字符,让外循环继续寻找这个字符在尾部。

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐