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);
        }
    };
    
  • 相关阅读:
    算法-在字符串中删除特定的字符或字符串
    Linux 下的7种文件类型
    TCP/IP协议、三次握手、四次挥手
    8、VUE自定义组件
    7、VUE事件
    6、VUE指令
    Redis高级功能-1、高并发基本概述
    5、插值
    4、VUE生命周期
    3、Vue实例的属性
  • 原文地址:https://www.cnblogs.com/deepend/p/14199375.html
Copyright © 2011-2022 走看看