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;
    }
  • 相关阅读:
    Windows Phone 7 日期选择控件DatePicker和时间选择控件TimePicker
    Windows Phone 7 开发小技巧
    Windows Phone 7 MVVM模式的学习笔记
    Windows Phone 7 网络编程之留言板应用
    C# 中的INotifyPropertyChanged和ObservableCollection<T>
    《深入浅出:Windows Phone 7应用开发》
    Windows Phone 7 MVVM模式通讯方式之实现Command
    Windows Phone 7 chart图表编程
    Windows Phone 7 网络编程之调用web service
    Perst嵌入式数据库介绍
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5062151.html
Copyright © 2011-2022 走看看