亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++實現(xiàn)LeetCode(76.最小窗口子串)

 更新時間:2021年07月17日 14:33:07   作者:Grandyang  
這篇文章主要介紹了C++實現(xiàn)LeetCode(76.最小窗口子串),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下

[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).

Example:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"

Note:

  • If there is no such window in S that covers all characters in T, return the empty string "".
  • If there is such window, you are guaranteed that there will always be only one unique minimum window in S.

這道題給了我們一個原字符串S,還有一個目標字符串T,讓在S中找到一個最短的子串,使得其包含了T中的所有的字母,并且限制了時間復雜度為 O(n)。這道題的要求是要在 O(n) 的時間度里實現(xiàn)找到這個最小窗口字串,暴力搜索 Brute Force 肯定是不能用的,因為遍歷所有的子串的時間復雜度是平方級的。那么來想一下,時間復雜度卡的這么嚴,說明必須在一次遍歷中完成任務,當然遍歷若干次也是 O(n),但不一定有這個必要,嘗試就一次遍歷拿下!那么再來想,既然要包含T中所有的字母,那么對于T中的每個字母,肯定要快速查找是否在子串中,既然總時間都卡在了 O(n),肯定不想在這里還浪費時間,就用空間換時間(也就算法題中可以這么干了,七老八十的富翁就算用大別野也換不來時間啊。依依東望,望的就是時間吶 T.T),使用 HashMap,建立T中每個字母與其出現(xiàn)次數(shù)之間的映射,那么你可能會有疑問,為啥不用 HashSet 呢,別急,講到后面你就知道用 HashMap 有多妙,簡直妙不可言~

目前在腦子一片漿糊的情況下,我們還是從簡單的例子來分析吧,題目例子中的S有點長,換個短的 S = "ADBANC",T = "ABC",那么肉眼遍歷一遍S唄,首先第一個是A,嗯很好,T中有,第二個是D,T中沒有,不理它,第三個是B,嗯很好,T中有,第四個又是A,多了一個,禮多人不怪嘛,收下啦,第五個是N,一邊涼快去,第六個終于是C了,那么貌似好像需要整個S串,其實不然,注意之前有多一個A,就算去掉第一個A,也沒事,因為第四個A可以代替之,第二個D也可以去掉,因為不在T串中,第三個B就不能再去掉了,不然就沒有B了。所以最終的答案就"BANC"了。通過上面的描述,你有沒有發(fā)現(xiàn)一個有趣的現(xiàn)象,先擴展,再收縮,就好像一個窗口一樣,先擴大右邊界,然后再收縮左邊界,上面的例子中右邊界無法擴大了后才開始收縮左邊界,實際上對于復雜的例子,有可能是擴大右邊界,然后縮小一下左邊界,然后再擴大右邊界等等。這就很像一個不停滑動的窗口了,這就是大名鼎鼎的滑動窗口 Sliding Window 了,簡直是神器啊,能解很多子串,子數(shù)組,子序列等等的問題,是必須要熟練掌握的啊!

下面來考慮用代碼來實現(xiàn),先來回答一下前面埋下的伏筆,為啥要用 HashMap,而不是 HashSet,現(xiàn)在應該很顯而易見了吧,因為要統(tǒng)計T串中字母的個數(shù),而不是僅僅看某個字母是否在T串中出現(xiàn)。統(tǒng)計好T串中字母的個數(shù)了之后,開始遍歷S串,對于S中的每個遍歷到的字母,都在 HashMap 中的映射值減1,如果減1后的映射值仍大于等于0,說明當前遍歷到的字母是T串中的字母,使用一個計數(shù)器 cnt,使其自增1。當 cnt 和T串字母個數(shù)相等時,說明此時的窗口已經(jīng)包含了T串中的所有字母,此時更新一個 minLen 和結(jié)果 res,這里的 minLen 是一個全局變量,用來記錄出現(xiàn)過的包含T串所有字母的最短的子串的長度,結(jié)果 res 就是這個最短的子串。然后開始收縮左邊界,由于遍歷的時候,對映射值減了1,所以此時去除字母的時候,就要把減去的1加回來,此時如果加1后的值大于0了,說明此時少了一個T中的字母,那么 cnt 值就要減1了,然后移動左邊界 left。你可能會疑問,對于不在T串中的字母的映射值也這么加呀減呀的,真的大丈夫(帶膠布)嗎?其實沒啥事,因為對于不在T串中的字母,減1后,變-1,cnt 不會增加,之后收縮左邊界的時候,映射值加1后為0,cnt 也不會減少,所以并沒有什么影響啦,下面是具體的步驟啦:

- 先掃描一遍T,把對應的字符及其出現(xiàn)的次數(shù)存到 HashMap 中。

- 然后開始遍歷S,就把遍歷到的字母對應的 HashMap 中的 value 減一,如果減1后仍大于等于0,cnt 自增1。

- 如果 cnt 等于T串長度時,開始循環(huán),紀錄一個字串并更新最小字串值。然后將子窗口的左邊界向右移,如果某個移除掉的字母是T串中不可缺少的字母,那么 cnt 自減1,表示此時T串并沒有完全匹配。

解法一:

class Solution {
public:
    string minWindow(string s, string t) {
        string res = "";
        unordered_map<char, int> letterCnt;
        int left = 0, cnt = 0, minLen = INT_MAX;
        for (char c : t) ++letterCnt[c];
        for (int i = 0; i < s.size(); ++i) {
            if (--letterCnt[s[i]] >= 0) ++cnt;
            while (cnt == t.size()) {
                if (minLen > i - left + 1) {
                    minLen = i - left + 1;
                    res = s.substr(left, minLen);
                }
                if (++letterCnt[s[left]] > 0) --cnt;
                ++left;
            }
        }
        return res;
    }
};

這道題也可以不用 HashMap,直接用個 int 的數(shù)組來代替,因為 ASCII 只有256個字符,所以用個大小為 256 的 int 數(shù)組即可代替 HashMap,但由于一般輸入字母串的字符只有 128 個,所以也可以只用 128,其余部分的思路完全相同,雖然只改了一個數(shù)據(jù)結(jié)構(gòu),但是運行速度提高了一倍,說明數(shù)組還是比 HashMap 快啊。還可以進一步的優(yōu)化,沒有必要每次都計算子串,只要有了起始位置和長度,就能唯一的確定一個子串。這里使用一個全局變量 minLeft 來記錄最終結(jié)果子串的起始位置,初始化為 -1,最終配合上 minLen,就可以得到最終結(jié)果了。注意在返回的時候要檢測一下若 minLeft 仍為初始值 -1,需返回空串,參見代碼如下:

解法二:

class Solution {
public:
    string minWindow(string s, string t) {
        vector<int> letterCnt(128, 0);
        int left = 0, cnt = 0, minLeft = -1, minLen = INT_MAX;
        for (char c : t) ++letterCnt[c];
        for (int i = 0; i < s.size(); ++i) {
            if (--letterCnt[s[i]] >= 0) ++cnt;
            while (cnt == t.size()) {
                if (minLen > i - left + 1) {
                    minLen = i - left + 1;
                    minLeft = left;
                }
                if (++letterCnt[s[left]] > 0) --cnt;
                ++left;
            }
        }
        return minLeft == -1 ? "" : s.substr(minLeft, minLen);
    }
};

到此這篇關于C++實現(xiàn)LeetCode(76.最小窗口子串)的文章就介紹到這了,更多相關C++實現(xiàn)最小窗口子串內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++?DLL注入工具(完整源碼)

    C++?DLL注入工具(完整源碼)

    這篇文章主要介紹了C++?DLL注入工具的相關資料,并向大家分享了完整的源碼,具有一定的參考價值,希望對正在工作或?qū)W習的你有所幫助
    2022-02-02
  • C++ 詳細講解stack與queue的模擬實現(xiàn)

    C++ 詳細講解stack與queue的模擬實現(xiàn)

    C++ Stack(堆棧) 是一個容器類的改編,為程序員提供了堆棧的全部功能,也就是說實現(xiàn)了一個先進后出(FILO)的數(shù)據(jù)結(jié)構(gòu),許多程序都使用了 queue 容器。queue 容器可以用來表示超市的結(jié)賬隊列或服務器上等待執(zhí)行的數(shù)據(jù)庫事務隊列
    2022-04-04
  • Qt實現(xiàn)簡單的TCP通信

    Qt實現(xiàn)簡單的TCP通信

    這篇文章主要為大家詳細介紹了Qt實現(xiàn)簡單的TCP通信,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Qt中QStringList與QString的常用方法總結(jié)

    Qt中QStringList與QString的常用方法總結(jié)

    這篇文章主要為大家總結(jié)了Qt中QString 與 (QStringList | QByteArray)之間的轉(zhuǎn)換,以及QString、QStringList的一些常用方法,感興趣的可以收藏一下
    2022-12-12
  • VC++的combobox控件用法匯總

    VC++的combobox控件用法匯總

    這篇文章主要介紹了VC++的combobox控件用法,對VC++初學者來說尤為重要,需要的朋友可以參考下
    2014-08-08
  • 數(shù)據(jù)結(jié)構(gòu) 中數(shù)制轉(zhuǎn)換(棧的應用)

    數(shù)據(jù)結(jié)構(gòu) 中數(shù)制轉(zhuǎn)換(棧的應用)

    這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu) 中數(shù)制轉(zhuǎn)換(棧的應用)的相關資料,需要的朋友可以參考下
    2017-06-06
  • Qt數(shù)據(jù)庫應用之實現(xiàn)通用數(shù)據(jù)庫清理

    Qt數(shù)據(jù)庫應用之實現(xiàn)通用數(shù)據(jù)庫清理

    項目如果需要存儲很多日志記錄比如運行日志,時間長了記錄數(shù)量非常多,數(shù)據(jù)庫體積不斷增大,對應數(shù)據(jù)庫表的增刪改查的效率不斷降低,因此需要將早期的數(shù)據(jù)清理。本文將詳細介紹一下通用數(shù)據(jù)庫清理的實現(xiàn),需要的可以參考一下
    2022-02-02
  • C語言細致講解線程同步的集中方式

    C語言細致講解線程同步的集中方式

    多線程中的線程同步可以使用,CreateThread,CreateMutex 互斥鎖實現(xiàn)線程同步,通過臨界區(qū)實現(xiàn)線程同步,Semaphore 基于信號實現(xiàn)線程同步,CreateEvent 事件對象的同步,以及線程函數(shù)傳遞單一參數(shù)與多個參數(shù)的實現(xiàn)方式
    2022-05-05
  • 使用C語言如何輸出逆序數(shù)

    使用C語言如何輸出逆序數(shù)

    逆序數(shù)的就是把一個數(shù)倒過來,例如:1234那么它的逆序數(shù)就為4321,我們該如何是實現(xiàn)呢?下面這篇文章主要給大家介紹了關于使用C語言如何輸出逆序數(shù)的相關資料,需要的朋友可以參考下
    2022-01-01
  • QT實戰(zhàn)之打開最近圖片功能的實現(xiàn)

    QT實戰(zhàn)之打開最近圖片功能的實現(xiàn)

    這篇文章主要為大家詳細介紹了如何利用Qt和QSettings實現(xiàn)打開最近圖片功能,文中的示例代碼講解詳細,對我們學習QT有一定的幫助,感興趣的可以了解一下
    2022-06-06

最新評論