zoukankan      html  css  js  c++  java
  • [LeetCode] 76. Minimum Window Substring 解题思路

    Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

    For example,
    S = "ADOBECODEBANC"
    T = "ABC"

    Minimum window is "BANC".

    Note:
    If there is no such window in S that covers all characters in T, return the empty string "".

    If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

    问题: 给定字符串 S 和 T ,求 S 中包含所有 T 中字符的最小子字符串。

    值得一提的是,“包含所有 T 中的字符”,是要包含 T 中所有字符以及对应的个数。在 T 中重复出现的字符,在最后答案中也需要包含相同个数的重复字符。第一次解没有理解到这个点,提出结果错误,意识到这个点后,修正并提交成功。

    解题思路采用的也是 滑动窗口算法(Slide Window Algorithm),LeetCode 把这样的算法归类到 双指针(Two Pointers)类型,算法思路和前面的 Longest Substring Without Repeating Characters 以及 Minimum Size Subarray Sum 相似。

    设下标 l 和 r,把左开右闭 [l, r) 想象成一个窗口。

    • 当窗口包含所有 T 中的字符时,则此时的窗口是一个可行解,l++
    • 当窗口没有包含所有 T 中的字符时,则 r++;

    如何判断窗口是否包含所有 T 中的字符呢?我使用了 map<char, alphStatus> 来表示,其中 alphStatus 只包含两个值:对应的字符在 T 中出现次数(target),以及当前窗口包含该字符的个数(cur)。可见,当 cur > target 时,对应字符满足被包含条件。

    当所有字符都满足被包含条件时,当前窗口便是一个可行解。

    找出所有可行解中窗口最小的,便是原题目的解。

    class alphStatus{
    public:
        int target = 0;
        int cur = 0;
    };
    
    string minWindow(string s, string t) {
        
        if (s.size() == 1) {
            return (s == t) ? s : "";
        }
        
        int l = 0;
        int r = 1;
        map<char, alphStatus> alph_status;
        
        for (int i = 0 ; i < t.size(); i++) {
            alph_status[t[i]].target++;
        }
        
        if (alph_status.count(s[0]) != 0) {
            alph_status[s[0]].cur = 1;
        }
        
        string res = s + "$";
        
        while (r <= s.size()) {
            
            bool isAllConted = true;
            
            map<char, alphStatus>::iterator m_iter;
            for (m_iter = alph_status.begin(); m_iter != alph_status.end(); m_iter++) {
                            
                if (m_iter->second.cur < m_iter->second.target) {
                    isAllConted = false;
                    break;
                }
            }        
            
            if ( isAllConted ) {
                
                if (r-l < res.size()) {
                    res = s.substr(l, r-l);
                }
                
                if (alph_status.count(s[l]) != 0) {
                    alph_status[s[l]].cur--;
                }
                l++;
                
            }else{
                
                if (r < s.size() && alph_status.count(s[r]) != 0) {
                    alph_status[s[r]].cur++;
                }
                r++;
            }
        }
        
        return ((int)res.size() == (int)s.size()+1) ? "" : res;
    }
  • 相关阅读:
    【转载】ESFramewor使用技巧(2)-- 在插件中使用NHibernate
    【转载】ESFramework介绍之(20)―― 插件自动升级
    [转载]我的架构经验小结(一)-- 常用的架构模型
    [转载]TCP服务器“拒绝服务攻击” 解决方案
    【转载】我的架构经验小结(三)-- 深入三层架构
    【转载】动态加载dll
    CSS3动画之一:Transitions功能
    CSS3中的transform变形
    [转载]插件开发
    【转载】服务器系统自动升级
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5062151.html
Copyright © 2011-2022 走看看