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);
        }
    };
    
  • 相关阅读:
    vue 中router-link下方的横线如何去除
    element-ui中如何去掉el-menu菜单栏中下划线
    vue中使用swiper做轮播页面,标题样式随着轮播页面改变而改变
    git pull失误提交
    通过计算机名获取本网段内电脑的IP地址和MAC地址
    C# 控件及常用设计整理
    TextBox控件中只输入整数的几种方法
    c#鼠标移动到Button 改变颜色
    C#编写条形码扫描
    C#编程中的crc16校验
  • 原文地址:https://www.cnblogs.com/deepend/p/14199375.html
Copyright © 2011-2022 走看看