Lintcode 32. 最小子串覆盖 && Leetcode 76. Minimum Window Substring
给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的最短子串。
如果在source中没有这样的子串,返回""。
如果有多个这样的子串,保证在source中始终只有一个唯一的最短子串。
目标字符串可能包含重复字符,最小窗口应覆盖所有字符,包括目标中的重复字符
class Solution { public: /** * @param source : A string * @param target: A string * @return: A string denote the minimum window, return "" if there is no such a string */ string minWindow(string &source , string &target) { // write your code here string str = ""; int slen = source.size(); int tlen = target.size(); if(slen <= 0 || tlen <= 0) { return ""; } int freq[256] = {0}; // 统计记录target串中字符 for(int i = 0; i < tlen; i++) { freq[target[i]]++; } int left = 0, right = -1; // 维持滑动窗口的两个索引 int tmp_l = 0, tmp_r = -1; // 记录当前覆盖子串的长度 int minLen = INT_MAX; // 记录最小的覆盖子串的长度,初始化尽可能的大 int count = tlen; // 计数, 子串的长度 while(left < slen) {
// 维持滑动窗口,思想:只针对出现在子串中的字符,计数操作,当前面的索引前进不动了(right增加受限了),就考虑后面的索引前进 if(right + 1 < slen && count > 0) { if(freq[source[right + 1]] > 0) { // 如果当前字符出现在target串中了,且在当前的子串中还没出现过,计数-1 count--; } freq[source[++right]]--; } else { // 当前字符hash计数-1,如果不是target串中的也要-1,此时值为负,标记了改字符在target串中不存在 if(freq[source[left]] >= 0) { count++; } freq[source[left++]]++; } while(count == 0) { if(minLen > right - left) { minLen = right - left + 1; tmp_l = left; tmp_r = right; } if(freq[source[left]] >= 0) { count++; } freq[source[left++]]++; } } for(int i = tmp_l; i <= tmp_r; i++) { str += source[i]; } return str; //return source.substr(tmp_l, tmp_r - tmp_l + 1); } };