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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

单调不减序列查询第一个大于等于_[力扣84,85] 单调栈

發(fā)布時(shí)間:2024/10/8 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单调不减序列查询第一个大于等于_[力扣84,85] 单调栈 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接

84. 柱狀圖中最大的矩形

85. 最大矩形

題目描述-84

給定 n 個(gè)非負(fù)整數(shù),用來表示柱狀圖中各個(gè)柱子的高度。每個(gè)柱子彼此相鄰,且寬度為 1 。

求在該柱狀圖中,能夠勾勒出來的矩形的最大面積。

樣例-84

輸入: [2,1,5,6,2,3]輸出: 10

題目描述-85

給定一個(gè)僅包含 0 和 1 的二維二進(jìn)制矩陣,找出只包含 1 的最大矩形,并返回其面積。

樣例-85

輸入:
[
["1","0","1","0","0"],
["1","0","1","1","1"],
["1","1","1","1","1"],
["1","0","0","1","0"]
]
輸出: 6

本題是要找到兩側(cè)第一個(gè)比它小的數(shù)的位置:找到每個(gè)柱形條左邊和右邊最近的比自己低的矩形條,然后用寬度乘高度,得到一個(gè)備選答案。這是單調(diào)棧的典型場景。

單調(diào)棧的核心使用場景:攤銷O(1)地獲得所有位置上兩側(cè)第一個(gè)比它大/小的數(shù)的位置

單調(diào)棧其它題目列表:

907. 子數(shù)組的最小值之和

739. 每日溫度

42. 接雨水

456. 132模式

注:驗(yàn)證前序遍歷序列是否為某個(gè)二叉搜索樹的問題,本質(zhì)上也是 132 模式的問題,如果前序遍歷序列不含 231 模式的子序列,則它是二叉搜索樹,依然用單調(diào)棧解。力扣上也有對應(yīng)題:255. 驗(yàn)證前序遍歷序列二叉搜索樹

496. 下一個(gè)更大元素 I

1019. 鏈表中的下一個(gè)更大節(jié)點(diǎn)

算法:單調(diào)棧

維護(hù)一個(gè)單調(diào)不減的棧,保存當(dāng)前枚舉元素 cur 左側(cè)小于等于 cur 的元素的下標(biāo),其中棧頂離cur 最近,它是 cur 左側(cè)第一個(gè)比它小的元素的位置。

枚舉數(shù)組所有下標(biāo) j,把所有大于 nums[j] 的棧頂都彈出,直到棧頂小于等于 nums[j],然后將 j 壓入(所有下標(biāo)都會(huì)壓入),當(dāng)前枚舉的 j 就處理完了。答案在出棧時(shí)更新,出棧元素為 cur

cur = st.top(); st.pop();

此時(shí)對于已經(jīng)彈出的 cur,當(dāng)前的棧頂是 cur 左側(cè)第一個(gè)小于等于 cur 的,nums[j] 是 cur 右側(cè)第一個(gè)大于 cur 的。cur 對應(yīng)的矩形寬度為

w = j - st.top() - 1;

當(dāng)棧頂有連續(xù)的幾個(gè)值相等的下標(biāo)時(shí),最后一個(gè)彈出的 cur 會(huì)把左側(cè)第一個(gè)小于 cur 的下標(biāo)取到,先彈出的取到的不是左側(cè)第一個(gè)小于 cur 的,只是第一個(gè)小于等于 cur的,這在此題不影響,但如果要返回每個(gè)位置能取到的最大矩形,則需要額外處理先彈出的幾個(gè)下標(biāo)。

棧底始終放一個(gè) -1 處理 nums[j] 比棧里所有元素都小的情況。

每個(gè)元素都要進(jìn)棧一次出棧一次,總時(shí)間復(fù)雜度 O(N)

對于第85題,M * N 的矩陣,一行一行地考慮,對于第 i 行,矩陣的第 0 到第 i 行可以視為一個(gè)直方圖,然后照搬 84 的做法求該直方圖上的最大矩形。一共有 M 個(gè)直方圖,總時(shí)間復(fù)雜度 O(MN)。

代碼-84(c++)

class Solution { public:int largestRectangleArea(vector<int>& heights) {if(heights.empty()) return 0;int n = heights.size();stack<int> st({-1});int result = 0;for(int i = 0; i < n; ++i){if(st.top() == -1 || heights[st.top()] <= heights[i])st.push(i);else{while(st.top() != -1 && heights[st.top()] > heights[i]){int index = st.top();st.pop();int w = i - st.top() - 1;int area = w * heights[index];result = max(result, area);}st.push(i);}}while(st.top() != -1){int index = st.top();st.pop();int w = n - st.top() - 1;int area = w * heights[index];result = max(result, area);}return result;} };

代碼-85(c++)

class Solution { public:int maximalRectangle(vector<vector<char>>& matrix) {if(matrix.empty()) return 0;int n = matrix.size(), m = matrix[0].size();vector<int> heights(m, 0);int result = 0;for(int i = 0; i < n; ++i){_get_geights(matrix, heights, i);int result_i = _max_rec_hist(heights);result = max(result, result_i);}return result;}private:void _get_geights(vector<vector<char> >& matrix, vector<int>& heights, int i){int m = matrix[0].size();for(int j = 0; j < m; ++j){int cnt = 0;int h = i;while(h >= 0 && matrix[h][j] == '1'){++cnt;--h;}heights[j] = cnt;}}int _max_rec_hist(vector<int>& heights){int m = heights.size();stack<int> st;st.push(-1);int result = 0;for(int j = 0; j < m; ++j){while(st.top() != -1 && heights[st.top()] > heights[j]){int h = heights[st.top()];st.pop();int l = st.top();int w = j - l - 1;result = max(result, h * w);}st.push(j);}while(st.top() != -1){int h = heights[st.top()];st.pop();int l = st.top();int w = m - l - 1;result = max(result, w * h);}return result;} };

總結(jié)

以上是生活随笔為你收集整理的单调不减序列查询第一个大于等于_[力扣84,85] 单调栈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。