zoukankan      html  css  js  c++  java
  • 32. 最小子串覆盖

    描述

    给定两个字符串 source 和 target. 求 source 中最短的包含 target 中每一个字符的子串.

    1. 如果没有答案, 返回 "".
    2. 保证答案是唯一的.
    3. target 可能包含重复的字符, 而你的答案需要包含至少相同数量的该字符.

    样例

    样例 1:

    输入: source = "abc", target = "ac"
    输出: "abc"
    

    样例 2:

    输入: source = "adobecodebanc", target = "abc"
    输出: "banc"
    解释: "banc" 是 source 的包含 target 的每一个字符的最短的子串.
    

    样例 3:

    输入: source = "abc", target = "aa"
    输出: ""
    解释: 没有子串包含两个 'a'.
    

    挑战

    O(n) 时间复杂度

    题解:

    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) {
            // 初始化counter_s和counter_t
            unordered_map<char, int> counter_t, counter_s;
            for (char c : target) {
                counter_t[c]++;
            }
    
            int left = 0, valid = 0;
            // 记录最小覆盖子串的起始索引及长度
            int start = -1, minlen = INT_MAX;
            for (int right = 0; right < source.size(); right ++){
                // 移动右边界, ch 是将移入窗口的字符
                char ch = source[right];
                if (counter_t.count(ch)) {
                    counter_s[ch]++;
                    if (counter_s[ch] == counter_t[ch])
                        valid++;
                }
    
                // 判断左侧窗口是否要收缩
                while (valid == counter_t.size()) {
                    // 更新最小覆盖子串
                    if (right - left < minlen) {
                        start = left;
                        minlen = right - left;
                    }
                // left_ch 是将移出窗口的字符
                char left_ch = source[left];
                // 左移窗口
                left ++;
                // 进行窗口内数据的一系列更新
                if (counter_t.count(left_ch)) {
                    if (counter_s[left_ch] == counter_t[left_ch])
                        valid--;
                    counter_s[left_ch] --;
                }                    
            }
        }
        // 返回最小覆盖子串
        return start == -1 ? "" : source.substr(start, minlen + 1);
        }
    };
    
  • 相关阅读:
    闪电侠 Netty 小册里的骚操作
    面试被问烂的 Spring IOC(求求你别再问了)
    面试问烂的 Spring AOP 原理、SpringMVC 过程(求求你别问了)
    使用 Cglib 实现多重代理
    Redis 初次见面
    Apollo 10 — adminService 全量发布
    Apollo 9 — adminService 主/灰度版本发布
    简析限流算法
    Dubbo 源码分析
    Dubbo 源码分析
  • 原文地址:https://www.cnblogs.com/deepend/p/14199375.html
Copyright © 2011-2022 走看看