色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

單調棧解題模板如何秒殺三道算法題

jf_78858299 ? 來源:labuladong ? 作者:labuladong ? 2023-04-19 10:52 ? 次閱讀

單調棧實際上就是棧,只是利用了一些巧妙的邏輯,使得 每次新元素入棧后,棧內的元素都保持有序 (單調遞增或單調遞減)。

本文就通過幾道算法題來看看單調棧模板的使用。

單調棧模板

首先,看一下 Next Greater Number 的原始問題,這是力扣第 496 題「下一個更大元素 I」:

給你一個數組,返回一個等長的數組,對應索引存儲著下一個更大元素,如果沒有更大的元素,就存 -1。

函數簽名如下:

vector<int> nextGreaterElement(vector<int>& nums);

比如說,輸入一個數組nums = [2,1,2,4,3],你返回數組[4,2,4,-1,-1]

解釋:第一個 2 后面比 2 大的數是 4; 1 后面比 1 大的數是 2;第二個 2 后面比 2 大的數是 4; 4 后面沒有比 4 大的數,填 -1;3 后面沒有比 3 大的數,填 -1。

這道題的暴力解法很好想到,就是對每個元素后面都進行掃描,找到第一個更大的元素就行了。但是暴力解法的時間復雜度是O(n^2)

這個問題可以這樣抽象思考:把數組的元素想象成并列站立的人,元素大小想象成人的身高。這些人面對你站成一列,如何求元素「2」的 Next Greater Number 呢?很簡單,如果能夠看到元素「2」,那么他后面可見的第一個人就是「2」的 Next Greater Number,因為比「2」小的元素身高不夠,都被「2」擋住了,第一個露出來的就是答案。

圖片

這個情景很好理解吧?帶著這個抽象的情景,先來看下代碼。

vector<int> nextGreaterElement(vector<int>& nums) {
    vector<int> res(nums.size()); // 存放答案的數組
    stack<int> s;
    // 倒著往棧里放
    for (int i = nums.size() - 1; i >= 0; i--) {
        // 判定個子高矮
        while (!s.empty() && s.top() <= nums[i]) {
            // 矮個起開,反正也被擋著了。。。
            s.pop();
        }
        // nums[i] 身后的 next great number
        res[i] = s.empty() ? -1 : s.top();
        // 
        s.push(nums[i]);
    }
    return res;
}

這就是單調隊列解決問題的模板。for 循環要從后往前掃描元素,因為我們借助的是棧的結構,倒著入棧,其實是正著出棧。while 循環是把兩個「個子高」元素之間的元素排除,因為他們的存在沒有意義,前面擋著個「更高」的元素,所以他們不可能被作為后續進來的元素的 Next Great Number 了。

這個算法的時間復雜度不是那么直觀,如果你看到 for 循環嵌套 while 循環,可能認為這個算法的復雜度也是O(n^2),但是實際上這個算法的復雜度只有O(n)

分析它的時間復雜度,要從整體來看:總共有n個元素,每個元素都被push入棧了一次,而最多會被pop一次,沒有任何冗余操作。所以總的計算規模是和元素規模n成正比的,也就是O(n)的復雜度。

問題變形

單調棧的使用技巧差不多了,來一個簡單的變形,力扣第 1118 題「一月有多少天」:

給你一個數組T,這個數組存放的是近幾天的天氣氣溫,你返回一個等長的數組,計算: 對于每一天,你還要至少等多少天才能等到一個更暖和的氣溫;如果等不到那一天,填 0

函數簽名如下:

vector<int> dailyTemperatures(vector<int>& T);

比如說給你輸入T = [73,74,75,71,69,76],你返回[1,1,3,2,1,0]

解釋:第一天 73 華氏度,第二天 74 華氏度,比 73 大,所以對于第一天,只要等一天就能等到一個更暖和的氣溫,后面的同理。

這個問題本質上也是找 Next Greater Number,只不過現在不是問你 Next Greater Number 是多少,而是問你當前距離 Next Greater Number 的距離而已。

相同的思路,直接調用單調棧的算法模板,稍作改動就可以,直接上代碼吧:

vector<int> dailyTemperatures(vector<int>& T) {
    vector<int> res(T.size());
    // 這里放元素索引,而不是元素
    stack<int> s; 
    /* 單調棧模板 */
    for (int i = T.size() - 1; i >= 0; i--) {
        while (!s.empty() && T[s.top()] <= T[i]) {
            s.pop();
        }
        // 得到索引間距
        res[i] = s.empty() ? 0 : (s.top() - i); 
        // 將索引入棧,而不是元素
        s.push(i); 
    }
    return res;
}

單調棧講解完畢,下面開始另一個重點:如何處理「循環數組」。

如何處理環形數組

同樣是 Next Greater Number,現在假設給你的數組是個環形的,如何處理?力扣第 503 題「下一個更大元素 II」就是這個問題:

比如輸入一個數組[2,1,2,4,3],你返回數組[4,2,4,-1,4]。擁有了環形屬性, 最后一個元素 3 繞了一圈后找到了比自己大的元素 4

一般是通過 % 運算符求模(余數),來獲得環形特效:

int[] arr = {1,2,3,4,5};
int n = arr.length, index = 0;
while (true) {
    print(arr[index % n]);
    index++;
}

這個問題肯定還是要用單調棧的解題模板,但難點在于,比如輸入是[2,1,2,4,3],對于最后一個元素 3,如何找到元素 4 作為 Next Greater Number。

對于這種需求,常用套路就是將數組長度翻倍

圖片

這樣,元素 3 就可以找到元素 4 作為 Next Greater Number 了,而且其他的元素都可以被正確地計算。

有了思路,最簡單的實現方式當然可以把這個雙倍長度的數組構造出來,然后套用算法模板。但是, 我們可以不用構造新數組,而是利用循環數組的技巧來模擬數組長度翻倍的效果

直接看代碼吧:

vector<int> nextGreaterElements(vector<int>& nums) {
    int n = nums.size();
    vector<int> res(n);
    stack<int> s;
    // 假裝這個數組長度翻倍了
    for (int i = 2 * n - 1; i >= 0; i--) {
        // 索引要求模,其他的和模板一樣
        while (!s.empty() && s.top() <= nums[i % n])
            s.pop();
        res[i % n] = s.empty() ? -1 : s.top();
        s.push(nums[i % n]);
    }
    return res;
}

這樣,就可以巧妙解決環形數組的問題,時間復雜度O(N)

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 算法
    +關注

    關注

    23

    文章

    4622

    瀏覽量

    93067
  • 數組
    +關注

    關注

    1

    文章

    417

    瀏覽量

    25980
收藏 人收藏

    評論

    相關推薦

    什么是模板匹配?模板匹配的原理講解 圖像處理與模板匹配算法

    目標。模板就是我們已知的在圖中要找的目標,且該目標同模板有相同的尺寸、方向和圖像,通過一定的算法可以在圖中找到目標,確定其坐標位置。 二:模板匹配的原理 用通俗的語言來解釋
    的頭像 發表于 05-05 09:25 ?3.4w次閱讀
    什么是<b class='flag-5'>模板</b>匹配?<b class='flag-5'>模板</b>匹配的原理講解 圖像處理與<b class='flag-5'>模板</b>匹配<b class='flag-5'>算法</b>

    嵌入式開發經典算法逆序

    不借助其他數據結構,如何實現的逆序?這是一非常經典的算法筆試題。
    發表于 08-06 17:10 ?380次閱讀

    單片機8031、四、五。一10元

    單片機8031、四、五。一10元,直接發我qq840921270 ,會給第一個采用
    發表于 04-16 17:02

    2018年全國大學生數學建模競賽B題解題程序----廣西大學 69隊

    ......星期四晚上拿到賽,按照慣例應該是請假全身心投入比賽,呃呃...然而并沒有請假...大致看了A、B兩,A題目短...估計坑多...于是選了B。。B
    發表于 05-31 12:15

    自動控制原理解題

    自動控制原理解題典是根據高等工科院校自動控制原理教學大綱的基本要求編寫的,書中例題涵蓋了經典控制理論和線性系統狀態空間分析的基本內容。全書共分九章,每章均
    發表于 07-11 09:01 ?93次下載
    自動控制原理<b class='flag-5'>解題</b><b class='flag-5'>題</b>典

    模板方法模式在回溯算法中的應用

    描述了模板方法模式及回溯算法模板方法模式的Java 語言實現,該實現使得回溯算法的實現達到了可擴展性、靈活性和可插入性個目標,提高了
    發表于 01-15 16:48 ?20次下載

    模板方法模式在回溯算法中的應用

    描述了模板方法模式及回溯算法模板方法模式的Java 語言實現,該實現使得回溯算法的實現達到了可擴展性、靈活性和可插入性個目標,提高了
    發表于 01-15 16:51 ?0次下載

    國內開發者在GitHub上開源LeetCode刷模板

    為了更好的與開發者分享自己的刷技巧,greyireland 在 GitHub 上開源了一套 LeetCode 刷模板:algorithm-pattern,主要記錄他通過各種刷文章
    的頭像 發表于 07-01 15:03 ?1835次閱讀
    國內開發者在GitHub上開源LeetCode刷<b class='flag-5'>題</b><b class='flag-5'>模板</b>!

    快來,我出個算法給你做做

    考大家一個算法 責任編輯:xj 原文標題:考大家一個算法 文章出處:【微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。
    的頭像 發表于 10-10 16:55 ?1404次閱讀

    一篇文章秒殺區間相關的問題

    經常有讀者問區間相關的問題,今天寫一篇文章,秒殺區間相關的問題。 所謂區間問題,就是線段問題,讓你合并所有線段、找出線段的交集等等。主要有兩個技巧: 1、排序。常見的排序方法就是按照區間起點排序
    的頭像 發表于 10-12 14:54 ?1912次閱讀
    一篇文章<b class='flag-5'>秒殺</b><b class='flag-5'>三</b><b class='flag-5'>道</b>區間相關的問題

    深入淺出了解單調單調隊列

    袁廚攜袁記菜館全體工作人員祝大家在新的一年,健健康康,開開心心。發量暴增,錢包超大。 哎,元旦假期結束了,又要繼續搬磚了,我們接著做題吧,今天我們好好說說單調單調隊列。其實很容易理解,單調
    的頭像 發表于 02-02 10:18 ?1497次閱讀
    深入淺出了解<b class='flag-5'>單調</b><b class='flag-5'>棧</b>和<b class='flag-5'>單調</b>隊列

    如何用DFS算法秒殺島嶼系列問題

    DFS/BFS 算法遍歷二維數組 。 本文主要來講解如何用 DFS 算法秒殺島嶼系列問題,不過用 BFS 算法的核心思路是完全一樣的,無非就是把 DFS 改寫成 BFS 而已。 那
    的頭像 發表于 11-16 17:13 ?1766次閱讀
    如何用DFS<b class='flag-5'>算法</b>來<b class='flag-5'>秒殺</b>島嶼系列問題

    DFS算法秒殺島嶼系列問題

    本文主要來講解如何用 DFS 算法秒殺島嶼系列問題,不過用 BFS 算法的核心思路是完全一樣的,無非就是把 DFS 改寫成 BFS 而已。
    的頭像 發表于 04-19 10:39 ?584次閱讀
    DFS<b class='flag-5'>算法</b><b class='flag-5'>秒殺</b>五<b class='flag-5'>道</b>島嶼系列問題

    數據結構解決滑動窗口問題

    前文用 [單調解決算法問題]介紹了單調這種特
    的頭像 發表于 04-19 10:50 ?668次閱讀
    數據結構解決滑動窗口問題

    滑動窗口算法解決子串問題教程

    難但太復雜,所以本文只選擇點贊最高,較為經典的,最能夠講明白的來講解。第一題為了讓讀者掌握算法模板,篇幅相對長,后兩
    的頭像 發表于 04-19 11:06 ?758次閱讀
    滑動窗口<b class='flag-5'>算法</b>解決子串問題教程
    主站蜘蛛池模板: 青青青青草| 国产午夜人做人免费视频中文| 日本aa大片| 久久国产亚洲电影天堂| 动漫女主被扒开双腿羞辱| 羽月希被黑人吃奶dasd585| 色中色最新地址登陆| 女人爽到高潮嗷嗷叫视频| 后入式狂顶免费视频| 粉嫩国产14xxxxx0000| 99爱在线精品视频网站| 亚洲野狼综合网站| 亚洲 欧美 制服 校园 动漫 | 九九这里有精品| 国产伦精品一区二区三区| 成人无码在线超碰视频| 99国产精品久久人妻无码| 伊人久久亚洲综合天堂| 亚洲国产成人一区二区在线| 色偷偷综合网| 日本阿v直播在线| 欧美18videosex性欧美老师| 恋夜影视列表免费安卓手机版 | 内射老妇BBX| 久久视频这有精品63在线国产| 韩国g奶空姐| 国产亚洲tv在线观看| 国产东北男同志videos网站| 成人免费在线视频| 办公室激情在线观看| wwwzzz日本| av女优快播| adc影院在线| ⅹxx日本护土| gay吊粗大双龙| 办公室中文BD| 成人免费视频一区| 大乳牛奶女magnet| 成人免费小视频| 国产超碰人人爱被IOS解锁| 高清观看ZSHH96的视频素材 |