【LeetCode】升級打怪之路 Day 12:單調隊列

今日題目:

  • 239. 滑動窗口最大值 | LeetCode

今天學習了單調隊列這種特殊的數據結構,思路很新穎,值得學習。

Problem:單調隊列 【必會】

與單調棧類似,單調隊列也是一種特殊的數據結構,它相比與普通的 queue,增加了一個新的接口 max() 來獲取當前隊列的最大值

新增的 max() 是我們選用這個數據結構的最重要原因,單調隊列不僅僅可以通過 offer()poll() 接口來實現 FIFO 的元素進出順序,還額外增加了 max() 接口讓我們獲取到當前隊列中的最大元素。

單調隊列主要用來解決下面這個場景:我們會時刻向一個集合中增加新元素或減少舊元素,同時每次可以獲取到當前這個集合中的最大值。優先級隊列也可以滿足這個需求,但優先級隊列無法滿足 FIFO 的元素進出順序,這也是必須使用單調隊列的原因。

假如有一個數組 window,并知道它的最大值是 A,此時向 window 增加一個新元素 B,我們只需要比較 A 和 B 就可以得到當前 window 中的最大值;但如果刪除一個舊元素 C,就麻煩了,因為如果這個刪除的 C 恰恰就是最大值 A,那么最大值就要重新遍歷 window 來尋找了,從而導致復雜度飆升。這就是單調隊列所需要解決的難題。

下面看一下單調隊列的經典應用:滑動窗口最大值

LC 239. 滑動窗口最大值 【classic】 ?????

239. 滑動窗口最大值 | LeetCode

如果我們能夠實現數據結構“單調隊列” MonoQueue,那我們就每次向右滑動我們的窗口時,向 monoQueue 中新增一個窗口右邊的新元素,移除一個窗口左邊的舊元素,然后調用 max() 接口獲取當前窗口的最大值,就可以計算出題目所需要的最終結果。

在這里插入圖片描述

所以重點在于如何實現 MonoQueue。

我們需求的關鍵是:需要能夠快速得知當前隊列中的最大值。由于窗口滑動時是有順序的,先進入的元素一定會先出去,所以如果新進入的一個元素,那么比它老的還比它小的那些元素就永遠不可能成為當前隊列中的最大值了,因為老元素一定會比新元素更早地離開隊列。所以,每次在入隊一個新元素時,就可以把隊列中比他小的元素都拋棄掉了

在這里插入圖片描述
如上圖,當元素 5 進入隊列后,就可以一下子把 4、3、2、1 全給拋棄掉了,因為這些舊元素在隊列的時候 5 一定在,所以這些舊元素一定成不了“當前隊列的最大值”。

根據以上分析,單調隊列 MonoQueue 的實現如下:

class MonoQueue {private Deque<Integer> maxQ = new LinkedList<>();public void offer(int num) {// 將小于 num 的元素全部刪除while (!maxQ.isEmpty() && maxQ.getLast() < num) {maxQ.removeLast();}// 將 num 加入隊尾maxQ.addLast(num);}public int max() {return maxQ.getFirst();  // 單調隊列,隊首就是最大元素}public void poll(int n) {if (maxQ.getFirst() == n) {  // 判斷需要移除的是否是隊首,如果不是的話,就是比隊首小還比隊首老的元素,已經被移除了,那就啥也不用干maxQ.removeFirst();}}
}

這里有兩個易錯點:

  • offer() 函數實現中,第一步刪掉掉小于 num 的元素,但注意別把等于它的元素刪除了,因為如果把相等的元素也刪掉的話,實現 poll() 接口時,就不太好判斷 隊首最大元素 是否就是我們當前需要 poll 的元素了(我們是通過值相等來判斷的)
  • 在實現 poll() 函數時,其參數 n 表示期待刪除的元素,因為我們這個 MonoQueue 并沒有保留全部入隊元素,所以當需要刪除一個已經被刪除的元素時,poll() 接口只需要立刻返回就可以了。

在實現了 MonoQueue 后,我們解決這個問題就容易多了:

    public int[] maxSlidingWindow(int[] nums, int k) {MonoQueue monoQueue = new MonoQueue();List<Integer> result = new ArrayList<>();// 將前 k-1 個元素填充到隊列中for (int i = 0; i < k - 1; i++) {monoQueue.offer(nums[i]);}for (int i = k - 1; i < nums.length; i++) {// 加入窗口右邊的新元素monoQueue.offer(nums[i]);// 獲取窗口內最大元素,并加入到結果集中result.add(monoQueue.max());// 移除窗口左邊的舊元素monoQueue.poll(nums[i - k + 1]);}return result.stream().mapToInt(Integer::valueOf).toArray();}

通過這個題,我們可以更加深入地理解單調隊列的具體用法。在有些情況下,我們除了在 MonoQueue 里面維護一個 maxQ 之外,還可以額外維護一個標準的 queue,從而對外表現出正常的 offer() 和 poll() 接口。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/718220.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/718220.shtml
英文地址,請注明出處:http://en.pswp.cn/news/718220.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Get Your Back Covered! Coverage, CodeCov和Tox

1. Coverage - 衡量測試的覆蓋率 我們已經掌握了如何進行單元測試。接下來,一個很自然的問題浮現出來,我們如何知道單元測試的質量呢?這就提出了測試覆蓋率的概念。覆蓋率測量通常用于衡量測試的有效性。它可以顯示您的代碼的哪些部分已被測試過,哪些沒有。 coverage.py …

Arm平臺下各種memcpy優化對比<二>

因memcpy導致tda4vm上的h264解碼占CPU較高而改棄&#xff0c;從網上找到各種memcpy的優化代碼&#xff0c;在一起做了個運行速度對比&#xff0c;請查收&#xff1b; #include <stdio.h> #include <stdlib.h> /* rand, srand */ #include <string.h> #i…

智慧公廁:打造智慧城市的環衛明珠

在城市建設中&#xff0c;公共衛生設施的完善和智能化一直是重要環節。而智慧公廁作為智慧城市建設的重要組成部分&#xff0c;發揮著不可替代的作用。本文以智慧公廁源頭實力廠家廣州中期科技有限公司&#xff0c;大量精品案例現場實景實圖&#xff0c;解讀智慧公廁如何助力打…

【數據結構】B樹

1 B樹介紹 B樹&#xff08;英語&#xff1a;B-tree&#xff09;&#xff0c;是一種在計算機科學自平衡的樹&#xff0c;能夠保持數據有序。這種數據結構能夠讓查找數據、順序訪問、插入數據及刪除的動作&#xff0c;都在對數時間內完成。B樹&#xff0c;概括來說是一個一般化的…

MySQL高可用性攻略:快速搭建MySQL主從復制集群 !

MySQL高可用性攻略&#xff1a;快速搭建MySQL主從復制集群 &#xff01; MySQL基礎知識&#xff1a;介紹MySQL數據庫的基本概念和常用命令&#xff0c;如何創建數據庫、表、用戶和權限管理等。 MySQL安裝教程&#xff1a;Centos7 安裝MySQL5.7.29詳細安裝手冊 MySQL數據類型&…

【大廠AI課學習筆記NO.63】模型的維護

說是模型的維護&#xff0c;其實這堂課都是在講“在工業環境中開發和部署機器學習模型的流程”。 上圖來自于我的筆記思維腦圖&#xff0c;已經上傳&#xff0c;要鏈接的訪問的主頁查看資源。 一路走來&#xff0c;我們學習了數據管理、模型學習、模型驗證、模型部署等重要的步…

arm板運行程序時尋找動態庫的路徑設置

問題&#xff1a;error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file&#xff1f; 第一種方法---- 解決&#xff1a; ①復制需要用到的arm庫到板子上。 ②pwd指令獲取該庫的絕對路徑&#xff0c;把路徑復制到/etc/ld.so.conf文件 ③輸…

Leetcoder Day37| 動態規劃part04 背包問題

01背包理論基礎 面試掌握01背包&#xff0c;完全背包和重背包就夠用了。 背包問題的理論基礎重中之重是01背包&#xff0c;一定要理解透&#xff01; 01 背包 有n件物品和一個最多能背重量為w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的價值是value[i] 。每件物品…

隱式馬爾科夫算法

隱式馬爾科夫算法 隱式馬爾科夫算法概述算法使用HMM 模型參數設置HMM 模型分類1. Gaussian HMM2. Multinomial HMM3. GMM HMM 其他機器學習算法&#xff1a;機器學習實戰工具安裝和使用 隱式馬爾科夫算法概述 隱式馬爾科夫算法是一種用于處理時序數據的強大工具&#xff0c;其…

css通過calc動態計算寬度

max-width: calc(100% - 40px) .m-mj-status-drawing-info-data{ display: inline-block; margin: 10px; min-width: 200px; padding: 10px;border-radius: 10px; background: #ddd;max-width: calc(100% - 40px);word-wrap: break-word;white-space: pre-line;}我開發的chatg…

計算機二級(Python)真題講解每日一題:《字典字符查找》

描述???????????????????????????????????????????????????????????????????????????????????????????????????????????????? 在右側的答題模板中&#xf…

Crash 實例

1.spinlock原理 為了解決這個spinlock的不公平問題&#xff0c;linux 2.6.25內核以后&#xff0c;spinlock采用了一種"FIFO ticket-based"算法的spinlock機制&#xff0c;可以很好的實現先來先搶占的思想。具體的做法如下&#xff1a; (1)、spinlock的核心字段有ow…

C語言-柔性數組成員的使用

文章目錄 摘要柔性數組成員基本使用細節探究 零長度數組-定長數組-變長數組 摘要 本文先介紹柔性數組成員(flexible array member)的基本使用&#xff0c;然后介紹其內存結構。最后&#xff0c;補充了一些數組相關的其他概念。 柔性數組成員 基本使用 參考: 【C語言內功修煉…

[項目設計] 從零實現的高并發內存池(一)

&#x1f308; 博客個人主頁&#xff1a;Chris在Coding &#x1f3a5; 本文所屬專欄&#xff1a;[高并發內存池] ?? 前置學習專欄&#xff1a;[Linux學習] ? 我們仍在旅途 ? 目錄 前言 項目介紹 1.內存池 1.1 什么是內存池 池化技術 內存池 1.2 為什…

word使用bib添加參考文獻

文章目錄 安裝TexLive安裝bibtex4word使用在word中添加參考文獻使用bibtex4word在word中添加參考文獻設置參考文獻格式為畢業論文格式 參考 安裝TexLive 從下載地址下載鏡像iso文件texlive2023.iso雙擊打開iso鏡像文件運行 install-tl-windows.bat點擊安裝非常非常非常耐心地安…

Shell學習 - 2.20 Shell exit命令:退出當前進程

exit 是一個 Shell 內置命令&#xff0c;用來退出當前 Shell 進程&#xff0c;并返回一個退出狀態&#xff1b;使用$?可以接收這個退出狀態&#xff0c;這一點已在《Shell $?》中進行了講解。 exit 命令可以接受一個整數值作為參數&#xff0c;代表退出狀態。如果不指定&…

Linux命令-clock命令(用于調整 RTC 時間)

說明 clock命令用于調整 RTC 時間。 RTC 是電腦內建的硬件時間&#xff0c;執行這項指令可以顯示現在時刻&#xff0c;調整硬件時鐘的時間&#xff0c;將系統時間設成與硬件時鐘之時間一致&#xff0c;或是把系統時間回存到硬件時鐘。 語法 clock [--adjust][--debug][--dir…

客戶端/服務器協議是啥意思?

客戶端/服務器協議是指在網絡通信中&#xff0c;客戶端和服務器之間進行數據傳輸時所使用的規定。簡單來說&#xff0c;客戶端是用戶使用的設備&#xff0c;如電腦或手機&#xff0c;而服務器則是提供數據或服務的遠程計算機。當客戶端需要獲取數據或服務時&#xff0c;它會向服…

【RT-DETR有效改進】結合SOTA思想利用雙主干網絡改進RT-DETR(全網獨家創新,重磅更新)

一、本文介紹 本文給大家帶來的改進機制是結合目前SOTAYOLOv9的思想利用雙主干網絡來改進RT-DETR&#xff08;本專欄目前發布以來改進最大的內容&#xff0c;同時本文內容為我個人一手整理全網獨家首發 | 就連V9官方不支持的模型寬度和深度修改我都均已提供&#xff0c;本文內…

【活動】金三銀四,前端工程師如何把握求職黃金期

隨著春意盎然的氣息彌漫大地&#xff0c;程序員群體中也迎來了一年一度的“金三銀四”求職熱潮。這個時間段對于廣大前端工程師而言&#xff0c;不僅象征著生機勃發的新起點&#xff0c;更是他們職業生涯中至關重要的轉折點。眾多知名公司在這一時期大規模開啟招聘通道&#xf…