日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java queue 最大值_[剑指offer题解]队列的最大值/滑动窗口的最大值

發布時間:2025/3/12 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java queue 最大值_[剑指offer题解]队列的最大值/滑动窗口的最大值 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

眾所周知,《劍指offer》是一本“好書”。

為什么這么說?

因為在技術面試中,它里面羅列的算法題在面試中出現的頻率是非常非常高的。

有多高,以我目前不多的面試來看,在所有遇到的面試算法題中,出現原題的概率大概能有6成,如果把基于原題的變種題目算上,那么這個出現概率能到達9成,10題中9題見過。

至于為什么給“好書”這兩個字打引號,因為這本書成了面試官的必備,如果考生不會這本書上的題目,就很可能得到面試官負面的評價。這本書快要成為評判學生算法能力的唯一標準,這使得考前突擊變成了一個慣例,反而讓投機倒把成了必要,并不一定能真正的考察考生的算法能力。

對于劍指offer題解這個系列,我的寫文章思路是,對于看了文章的讀者,能夠:

迅速了解該題常見解答思路(奇技淫巧不包括在內,節省大家時間,實在有研究需求的人可以查閱其它資料)

思路盡量貼近原書(例如書中提到的面試官經常會要求不改變原數組,或者有空間限制等,盡量體現在代碼中,保證讀者可以不漏掉書中細節)

盡量精簡話語,避免冗長解釋

給出代碼可運行,注釋齊全,對細節進行解釋

快速找到我的《劍指offer題解》專欄:

公眾號(Rude3Knife):底部導航欄——劍指offer題解

CSDN(@Rude3Knife):劍指offer題解專欄

題目介紹

劍指offer面試題59題

給定一個數組和滑動窗口的大小,找出所有滑動窗口里數值的最大值。例如,如果輸入數組{2,3,4,2,6,2,5,1}及滑動窗口的大小3,那么一共存在6個滑動窗口,他們的最大值分別為{4,4,6,6,6,5};針對數組{2,3,4,2,6,2,5,1}的滑動窗口有以下6個:{[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

解題思路

方法一:蠻力法

思路

掃描窗口k,得到最大值。對于長度為n的數組,算法時間復雜度O(nk)

顯然不是最優解。

方法二:用兩個棧實現隊列

思路

面試題30中,我們實現過用兩個棧實現了隊列,可以在O(1)時間得到棧的最大值,也就可以得到隊列的最大值。

這樣總的時間復雜度O(n)

但是這樣的思路寫代碼,等于同時要寫兩個題目,面試時間可能不允許。

方法三:雙端隊列

思路

參考解釋:

數組的第一個數字是2,把它存入隊列中。第二個數字是3,比2大,所以2不可能是滑動窗口中的最大值,因此把2從隊列里刪除,再把3存入隊列中。第三個數字是4,比3大,同樣的刪3存4。此時滑動窗口中已經有3個數字,而它的最大值4位于隊列的頭部。

第四個數字2比4小,但是當4滑出之后它還是有可能成為最大值的,所以我們把2存入隊列的尾部。下一個數字是6,比4和2都大,刪4和2,存6。就這樣依次進行,最大值永遠位于隊列的頭部。

但是我們怎樣判斷滑動窗口是否包括一個數字?應該在隊列里存入數字在數組里的下標,而不是數值。當一個數字的下標與當前處理的數字的下標之差大于或者相等于滑動窗口大小時,這個數字已經從窗口中滑出,可以從隊列頭部把它刪除。因此,我們既有可能從頭部刪除數字,又可能從尾部刪除數字,所以要雙端隊列。

代碼

注意點:

ArrayDeque的幾個API:pollFirst、peekFirst等

ArrayDeque保存的是下標

最新的數的下標是必定加進去的。

import java.util.ArrayList;

import java.util.ArrayDeque;

public class Solution {

public ArrayList maxInWindows(int [] num, int size)

{

ArrayList result = new ArrayList<>();

// 排除特殊情況,窗口的長度為0

if (size==0) return result;

// 滑動窗口最左邊數的index

int begin;

// 建立一個雙端隊列

ArrayDeque q = new ArrayDeque<>();

for(int i=0;i

// begin是窗口起始位置

begin = i-size+1;

// 隊列空,直接加入

if(q.isEmpty())

q.add(i);

// 若隊列最左邊值已經不在窗口內,直接刪除

else if(begin > q.peekFirst())

q.pollFirst();

// 從隊尾開始比較,把所有比他小的值丟掉

while((!q.isEmpty()) && num[q.peekLast()] <= num[i])

q.pollLast();

// 隨后再把它放進去

q.add(i);

// 若窗口起始位置在數組的0位置上或者之后(窗口是完整大小的),才計算窗口的有效最大值

if(begin>=0){

// 永遠是隊列最左邊最大,加入結果集

result.add(num[q.peekFirst()]);

}

}

return result;

}

}

總結

采用雙端隊列,非常巧妙地一題。

關注我

我目前是一名后端開發工程師。技術領域主要關注后端開發,數據爬蟲,數據安全,5G,物聯網等方向。

微信:yangzd1102

Github:@qqxx6661

個人博客:

CSDN:@qqxx6661

知乎:@Zhendong

簡書:@蠻三刀把刀

掘金:@蠻三刀把刀

原創博客主要內容

Java知識點復習全手冊

Leetcode算法題解析

劍指offer算法題解析

SpringCloud菜鳥入門實戰系列

SpringBoot菜鳥入門實戰系列

Python爬蟲相關技術文章

后端開發相關技術文章

個人公眾號:Rude3Knife

個人公眾號:Rude3Knife

如果文章對你有幫助,不妨收藏起來并轉發給您的朋友們~

總結

以上是生活随笔為你收集整理的java queue 最大值_[剑指offer题解]队列的最大值/滑动窗口的最大值的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。