【LeetCode】升級打怪之路 Day 11 加餐:單調隊列

今日題目:

  • 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/716565.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716565.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716565.shtml

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

相關文章

【NR 定位】3GPP NR Positioning 5G定位標準解讀(一)

目錄 前言 1. 3GPP規劃下的5G技術演進 2. 5G NR定位技術的發展 2.1 Rel-16首次對基于5G的定位技術進行標準化 2.2 Rel-17進一步提升5G定位技術的性能 3. Rel-18 關于5G定位技術的新方向、新進展 3.1 Sidelink高精度定位功能 3.2 針對上述不同用例&#xff0c;3GPP考慮按…

自動駕駛---Motion Planning之Speed Boundary(上)

1 背景 在上篇博客《自動駕駛---Motion Planning之Path Boundary》中,筆者主要介紹了path boundary的一些內容,通過將道路中感興趣區域的動靜態障礙物投影到車道坐標系中,用于確定L或者S的邊界,并利用道路信息再確定Speed的邊界,最后結合粗糙的速度曲線和路徑曲線,即可使…

Go-知識簡短變量聲明

Go-知識簡短變量聲明 1. 簡短變量聲明符2. 簡短變量賦值可能會重新聲明3. 簡短變量賦值不能用于函數外部4. 簡短變量賦值作用域問題5. 總結 githuio地址&#xff1a;https://a18792721831.github.io/ 1. 簡短變量聲明符 在Go語言中&#xff0c;可以使用關鍵字var或直接使用簡短…

【STK】手把手教你利用STK進行仿真-STK軟件基礎02 STK系統的軟件界面01 STK的界面窗口組成

STK系統是Windows窗口類型的桌面應用軟件,功能非常強大。在一個桌面應用軟件中集成了仿真對象管理、仿真對象屬性參數、設置、空間場景二三維可視化、場景顯示控制欲操作、仿真結果報表定制與分析、對象數據管理、仿真過程控制、外部接口連接和系統集成編程等復雜的功能。 STK…

SpringBoot之Actuator的兩種監控模式

SpringBoot之Actuator的兩種監控模式 springboot提供了很多的檢測端點(Endpoint),但是默認值開啟了shutdown的Endpoint&#xff0c;其他默認都是關閉的,可根據需要自行開啟 文章目錄 SpringBoot之Actuator的兩種監控模式1. pom.xml2. 監控模式1. HTTP2. JMX 1. pom.xml <de…

力扣 第 125 場雙周賽 解題報告 | 珂學家 | 樹形DP + 組合數學

前言 整體評價 T4感覺有簡單的方法&#xff0c;無奈樹形DP一條路上走到黑了&#xff0c;這場還是有難度的。 T1. 超過閾值的最少操作數 I 思路: 模擬 class Solution {public int minOperations(int[] nums, int k) {return (int)Arrays.stream(nums).filter(x -> x <…

VM虛擬機無法傳輸文件(更新時間24/3/3)

出現這個問題一般是未安裝VMware Tools 以下為手動安裝教程及可能出現的問題的解決方法&#xff1a; 1. 準備安裝 2.用cmd手動啟動安裝 3. 安裝過程默認即可&#xff0c;直接一直下一步 4.安裝完成后會自動重啟虛擬機&#xff08;沒有的話手動重啟即可&#xff09; 5.重啟以后…

Web應用安全威脅與防護措施

本文已收錄至《全國計算機等級考試——信息 安全技術》專欄 由于極其容易出現漏洞、并引發安全事故&#xff0c;因此數據隱私的保護是目前絕大多數企業不可繞過的運維環節。不過&#xff0c;許多中小型企業往往會錯誤地認為只有大型企業才會成為黑客的目標。而實際統計數字卻截…

StarCoder2模型,釋放你的大模型編碼潛能

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎&#xff1f;訂閱我們的簡報&#xff0c;深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同&#xff0c;從行業內部的深度分析和實用指南中受益。不要錯過這個機會&#xff0c;成為AI領…

DeepSpeed-Chat RLHF 階段代碼解讀(0) —— 原始 PPO 代碼解讀

為了理解 DeepSpeed-Chat RLHF 的 RLHF 全部過程&#xff0c;這個系列會分三篇文章分別介紹&#xff1a; 原始 PPO 代碼解讀RLHF 獎勵函數代碼解讀RLHF PPO 代碼解讀 這是系列的第一篇文章&#xff0c;我們來一步一步的看 PPO 算法的代碼實現&#xff0c;對于 PPO 算法原理不太…

部署若依前后端分離項目,連接數據庫失敗

部署若依前后端分離項目&#xff0c;連接數據庫失敗&#xff0c;異常如下&#xff1a; 解決方案&#xff1a;application配置文件里&#xff0c;連接數據庫的參數useSSL的值改為false

leetcode 長度最小的子數組

在本題中&#xff0c;我們可以知道&#xff0c;是要求數組中組成和為target的最小子數組的長度。所以&#xff0c;我們肯定可以想到用兩層for循環進行遍歷&#xff0c;然后枚舉所有的結果進行挑選&#xff0c;但這樣時間復雜度過高。 我們可以采用滑動窗口&#xff0c;其實就是…

編寫dockerfile掛載卷、數據容器卷

編寫dockerfile掛載卷 編寫dockerfile文件 [rootwq docker-test-volume]# vim dockerfile1 [rootwq docker-test-volume]# cat dockerfile1 FROM centosVOLUME ["volume01","volume02"]CMD echo "------end------" CMD /bin/bash [rootwq dock…

2024 年廣東省職業院校技能大賽(高職組)“云計算應用”賽項樣題 2

#需要資源或有問題的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要資源或有問題的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要資源或有問題的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; 某企業根據自身業務需求&#…

每日OJ題_牛客_合法括號序列判斷

目錄 合法括號序列判斷 解析代碼 合法括號序列判斷 合法括號序列判斷__牛客網 解析代碼 class Parenthesis {public:bool chkParenthesis(string A, int n){if (n & 1) // 如果n是奇數return false;stack<char> st;for (int i 0; i < n; i) {if (A[i] () {s…

筆記本hp6930p安裝Android-x86補記

在上一篇日記中&#xff08;筆記本hp6930p安裝Android-x86避坑日記-CSDN博客&#xff09;提到hp6930p安裝Android-x86-9.0&#xff0c;無法正常啟動&#xff0c;本文對此再做嘗試&#xff0c;原因是&#xff1a;Android-x86-9.0不支持無線網卡&#xff0c;需要在BIOS中關閉WLAN…

《Docker極簡教程》--Docker的高級特性--Docker Compose的使用

Docker Compose是一個用于定義和運行多容器Docker應用程序的工具。它允許開發人員通過簡單的YAML文件來定義應用程序的服務、網絡和卷等資源&#xff0c;并使用單個命令來啟動、停止和管理整個應用程序的容器。以下是關于Docker Compose的一些關鍵信息和優勢&#xff1a; 定義…

B082-SpringCloud-Eureka

目錄 微服務架構與springcloud架構演變為什么使用微服務微服務的通訊方式架構的選擇springcloud概述場景模擬之基礎架構的搭建模擬微服務之間的服務調用目前遠程調用的問題 eureka注冊中心的作用注冊中心的實現服務提供者注冊到注冊中心 springcloud基于springboot 微服務架構與…

10 計算機結構

馮諾依曼體系結構 馮諾依曼體系結構&#xff0c;也被稱為普林斯頓結構&#xff0c;是一種計算機架構&#xff0c;其核心特點包括將程序指令存儲和數據存儲合并在一起的存儲器結構&#xff0c;程序指令和數據的寬度相同&#xff0c;通常都是16位或32位 我們常見的計算機,筆記本…

在Centos7中用Docker部署gitlab-ce

一、介紹 GitLab Community Edition (GitLab CE) 是一個開源的版本控制系統和協作平臺&#xff0c;用于管理和追蹤軟件開發項目。它提供了一套完整的工具和功能&#xff0c;包括代碼托管、版本控制、問題跟蹤、持續集成、持續交付和協作功能&#xff0c;使團隊能夠更加高效地進…