單調堆疊
本人小學雞,寫博客僅為強化記憶,分享交流,如有錯誤請多指正,
何為單調堆疊?
顧名思義,就是單調的堆疊,我們維護一個堆疊,堆疊中的元素保持非嚴格單調遞增或遞減,
此演算法在處理一些問題時莫名其妙(霧)的有效,是一個典型的空間換時間的演算法,
1. 最大的矩形 [CSP]201312-3 / [LeetCode] 84.
問題描述
在橫軸上放了n個相鄰的矩形,每個矩形的寬度是1,而第i(1 ≤ i ≤ n)個矩形的高度是hi,這n個矩形構成了一個直方圖,例如,下圖中六個矩形的高度就分別是3, 1, 6, 5, 2, 3,
請找出能放在給定直方圖里面積最大的矩形,它的邊要與坐標軸平行,對于上面給出的例子,最大矩形如下圖所示的陰影部分,面積是10,

輸入格式
第一行包含一個整數n,即矩形的數量(1 ≤ n ≤ 1000),
第二行包含n 個整數h1, h2, … , hn,相鄰的數之間由空格分隔,(1 ≤ hi ≤ 10000),hi是第i個矩形的高度,
輸出格式
輸出一行,包含一個整數,即給定直方圖內的最大矩形的面積,
樣例輸入
6
3 1 6 5 2 3
樣例輸出
10
題解
我們可以維持一個單調遞增的堆疊,為了便于計算矩形寬度,我們在堆疊里存放單個矩形的位置,
我們從左到右遍歷高度陣列,對于每個矩形的高度p,如果p大于等于當前堆疊頂儲存位置的高度q,我們將p的位置也壓入堆疊中;
如果p小于q,我們將q彈出,紀錄高度,并記錄當前遍歷到的矩形p與新堆疊頂位置之差(實際上還需要減1),作為寬度,并更新結果,
為避免堆疊中剩余矩形,我們可以在陣列尾插入一個高度為零的矩形,使堆疊中所有矩形彈出并更新,
代碼實作
int largestRectangleArea(vector<int>& heights) {
heights.push_back(0); //插入空矩形,彈出堆疊中剩余矩形
int len = heights.size(), area = 0, pre_index, height, width;
stack<int> indices;
for (int i = 0; i < len; i++) {
while (!indices.empty() && heights[indices.top()] > heights[i]) { //檢查堆疊是否為空
pre_index = indices.top(); //儲存堆疊頂矩形的位置
indices.pop();
height = heights[pre_index]; //儲存高度
if (indices.empty()) { //避免操作空堆疊
width = i; //若彈出至堆疊為空,因堆疊的遞增性,邊界可向左延伸至0
} else {
width = i - indices.top() - 1; //儲存寬度
}
area = area > (width * height) ? area : (width * height); //更新結果
}
indices.push(i);
}
return area;
}
2.每日溫度 [LeetCode] 739.
問題描述
請根據每日 氣溫 串列,重新生成一個串列,對應位置的輸出為:要想觀測到更高的氣溫,至少需要等待的天數,如果氣溫在這之后都不會升高,請在該位置用 0 來代替,
例如,給定一個串列 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的輸出應該是 [1, 1, 4, 2, 1, 1, 0, 0],
提示:氣溫 串列長度的范圍是 [1, 30000],每個氣溫的值的均為華氏度,都是在 [30, 100] 范圍內的整數,
題解
我們在這里維持一個單調遞減的堆疊,為了便于計算天數差,我們在堆疊中儲存位置(即日期),
此題相較上題簡單一些,故不在此贅述,
注意:
此題與上題不同的是,若堆疊中有剩余的日期,說明此后沒有更暖和的日期,故無需再彈出,
代碼實作
vector<int> dailyTemperatures(vector<int>& T) {
int n = T.size(), pre_index;
vector<int> ans(n);
stack<int> indices;
for (int i = 0; i < n; i++) {
while (!indices.empty() && T[indices.top()] < T[i]) {
pre_index = indices.top();
indices.pop();
ans[pre_index] = i - pre_index; //計算日期差
}
indices.push(i);
}
return ans;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/236692.html
標籤:其他
下一篇:springcloud 專案原始碼 微服務 分布式 flowable作業流 vue.js html 跨域 前后分離
