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); } };
原文地址:https://www.cnblogs.com/zhang716921/p/10690418.html