棧和佇列:滑動視窗和陣列變樹問題
1.滑動視窗問題
有一個整型陣列 arr 和一個大小為 w 的視窗從陣列的最左邊滑到最右邊,視窗每次向右邊滑一個位置。 返回一個長度為n-w+1的陣列res,res[i]表示每一種視窗狀態下的最大值。 以陣列為[4,3,5,4,3,3,6,7],w=3為例。因為第一個視窗[4,3,5]的最大值為5,第二個視窗[3,5,4]的最大值為5,第三個視窗[5,4,3]的最大值為5。第四個視窗[4,3,3]的最大值為4。第五個視窗[3,3,6]的最大值為6。第六個視窗[3,6,7]的最大值為7。所以最終返回[5,5,5,4,6,7]。
給定整形陣列arr及它的大小n,同時給定w,請返回res陣列。保證w小於等於n,同時保證陣列大小小於等於500。
思路:
普通方法,對於n個元素,每個視窗m次比較,時間複雜度O(nm)的原地解決方案。藉助雙端佇列來實現時間複雜度
O(n)
雙端佇列qmax存陣列中的下標,其中對頭---當前視窗下最大值的下標,在隊尾的push和pop是為了使當對頭彈出時,
能夠滿足後面的更小的值。
(1)佇列為空,直接將i入隊
(2)佇列不為空,在佇列尾部彈出下標 j,直到a[j]>a[i],把i入隊尾
(3)對頭下標top為i-w時,要彈出對頭,因為此時對頭已過期。
public class SlideWindow {
public int[] slide(int[] arr, int n, int w) {
// write code here
if(arr==null||n<1||w<1) return null;
Deque<Integer> qmax=new LinkedList();//雙端佇列,對頭儲存視窗內最大值位置,隊尾就是對下標更新,確保能夠包含後面出現的更小的值
int res[]=new int[n-w+1];
int index=0;
for(int i=0;i<n;i++){//對於每個元素
while(!qmax.isEmpty()&&arr[qmax.peekLast()]<=arr[i]){//佇列不空,彈出隊尾j,a[j]>a[i]的時候,
qmax.pollLast();
}
qmax.add(i);//如果佇列為空,直接將下標i入隊
if(qmax.peekFirst()==i-w){//對頭元素為視窗內最大值下標,但若==i-w,說明該對頭不在視窗內,要彈出
qmax.pollFirst();
}
if(i>=w-1){//儲存視窗的最大值
res[index++]=arr[qmax.peekFirst()];
}
}
return res;
}
}
2.陣列變樹問題
對於一個沒有重複元素的整數陣列,請用其中元素構造一棵MaxTree,MaxTree定義為一棵二叉樹,其中的節
點與數組元素一一對應,同時對於MaxTree的每棵子樹,它的根的元素值為子樹的最大值。現有一建樹方法,對於數
組中的每個元素,其在樹中的父親為陣列中它左邊比它大的第一個數和右邊比它大的第一個數中更小的一個。若
兩邊都不存在比它大的數,那麼它就是樹根。請設計時間複雜度為O(n)的演算法。給定一個無重複元素的陣列A和它的
大小n,請返回一個陣列,其中每個元素為原陣列中對應位置元素在樹中的父親節點的編號,若為根則值為-1。
例如:輸入數字{3,1,4,2}
返回陣列:{2,0,-1,2}
思路:使用result[]記錄對陣列中每個元素的父節點下標,初始值-1。其中父節點的判斷使用輔助棧完成。
首先棧用來查詢陣列中元素x,往左第一個>x的元素下標,往右第一個>x的下標。
上述例子:
(1)當棧空時,直接將元素下標入棧,該棧左邊不存在>它的元素,比如3,此時res[3]=-1
(2)當棧不為空,元素x<棧頂a[top],則下標top對應的元素就是x左邊第一個比他大的。此時res[1]=0;
(3)當棧不為空,x>a[top],則彈出棧top,說明x左邊沒有比他大的,pop出top,將x下標入棧。並且此時說明
a[top]右邊第一個>a[top]的是x. 所以res[top]=x的下標,即:res[0]=2;
最後:下標仍為-1的就是根,然後其他節點指向他們父節點的下標。
相關文章
- 佇列和棧佇列
- 棧和佇列佇列
- [Leetcode]雙項佇列解決滑動視窗最大值難題LeetCode佇列
- 【程式碼隨想錄】一、陣列:4.滑動視窗陣列
- 程式碼隨想錄陣列二刷:長度最小的子陣列(滑動視窗)陣列
- Chapter 2 棧和佇列APT佇列
- 滑動視窗問題總結
- [劍指offer題解][Java]佇列的最大值/滑動視窗的最大值Java佇列
- Java面試題:棧和佇列的實現Java面試題佇列
- 《演算法》- 佇列和棧演算法佇列
- 陣列和指標的問題陣列指標
- 2. 揹包,佇列和棧佇列
- time模組,collections模組,佇列和棧佇列
- 資料結構—棧和佇列資料結構佇列
- 資料結構(棧和佇列)資料結構佇列
- 【資料結構】--棧和佇列資料結構佇列
- C#實現棧和佇列C#佇列
- 單調棧 和 單調佇列佇列
- 單調棧和單調佇列佇列
- 陣列--移除陣列中指定的元素,不改變原陣列和改變原陣列陣列
- JavaScript資料結構之陣列棧佇列JavaScript資料結構陣列佇列
- 聊聊陣列與連結串列,棧與佇列陣列佇列
- vue 陣列和物件渲染問題Vue陣列物件
- 陣列累加和問題三連陣列
- 子陣列異或和問題陣列
- 滑動視窗法——子串相關問題
- 佇列,棧佇列
- 棧、佇列佇列
- 棧-佇列佇列
- TCP的滑動視窗和擁塞控制TCP
- 演算法之美:棧和佇列演算法佇列
- 資料結構之棧和佇列資料結構佇列
- 佇列 和 迴圈佇列佇列
- 樹狀陣列和逆序對陣列
- 9. 題目:對佇列實現棧&用棧實現佇列佇列
- 洛谷題單指南-常見最佳化技巧-P1886 滑動視窗 /【模板】單調佇列佇列
- 畫江湖之資料結構【第二話:佇列和棧】佇列資料結構佇列
- 畫江湖之資料結構 [第二話:佇列和棧] 佇列資料結構佇列