【代碼隨想錄】【算法訓練營】【第55天】 [42]接雨水 [84]柱狀圖中最大的矩形

前言

思路及算法思維,指路 代碼隨想錄。
題目來自 LeetCode。

day 55,又是一個周一,不能再堅持~

題目詳情

[42] 接雨水

題目描述

42 接雨水
42 接雨水

解題思路

前提:雨水形成的情況是凹的, 需要前中后3個元素,計算該元素左右兩側的第一個大于該高度的高度
思路:單調遞增棧
重點:單調棧的思維

代碼實現

C語言
單調遞增棧

單調遞增棧: 【橫向計算形成凹行柱體的雨水】
雨水形成的情況是凹的, 需要當前新的棧頂元素, 計算的是舊的棧頂元素形成的雨水

// 單調遞增棧: 雨水形成的情況是凹的, 需要當前新的棧頂元素, 計算的是舊的棧頂元素形成的雨水int minFun(int p1, int p2)
{return p1 < p2 ? p1 : p2;
}int trap(int* height, int heightSize) {int stack[heightSize];int top = 0;// 遍歷計算每個柱子接到的雨水之和int sum = 0;for (int i = 0; i < heightSize; i++) {// 單調遞增棧// 當前元素比棧頂元素大,不滿足單調遞增棧的要求while (top > 0 && height[i] > height[stack[top - 1]]) {//  彈出當前棧頂元素int midIndex = stack[top - 1];top--;// 雨水形成的情況是凹的, 需要當前新的棧頂元素, 計算的是舊的棧頂元素形成的雨水if (top > 0) {int leftIndex = stack[top - 1];sum += (minFun(height[leftIndex], height[i]) - height[midIndex]) * (i - leftIndex - 1);}}stack[top] = i;top++;}return sum;
}
雙指針

雙指針解法:【豎向計算每個柱體形成的雨水】
兩次遍歷求當前左側最高柱子高度maxLeft[i]和右側最高柱子高度maxRight[i]

// 雙指針解法:兩次遍歷求當前左側最高柱子高度maxLeft[i]和右側最高柱子高度maxRight[i]int maxFun(int p1, int p2)
{return p1 > p2 ? p1 : p2;
}int minFun(int p1, int p2)
{return p1 < p2 ? p1 : p2;
}int trap(int* height, int heightSize) {int maxLeft[heightSize];int maxRight[heightSize];// 遍歷搜索左側最高柱子高度maxLeft[0] = height[0];for (int i = 1; i < heightSize; i++) {maxLeft[i] = maxFun(height[i], maxLeft[i - 1]);}// 遍歷搜索右側最高柱子高度maxRight[heightSize - 1] = height[heightSize - 1];for (int j = heightSize - 2; j >= 0; j--) {maxRight[j] = maxFun(height[j], maxRight[j + 1]);}// 遍歷計算每個柱子接到的雨水之和int sum = 0;for (int k = 0; k < heightSize; k++) {sum += minFun(maxLeft[k], maxRight[k]) - height[k];}return sum;
}

[84] 柱狀圖中最大的矩形

題目描述

84 柱狀圖中最大的矩形
84 柱狀圖中最大的矩形

解題思路

前提:柱狀圖形成的最大面積,需要求解該柱子左右兩側 最遠>=該柱子高度的柱子寬度,即可以求解該柱子左右兩側小于該柱子高度的位置,進而計算所求寬度
思路:單調遞減棧
重點:單調棧的思維

代碼實現

C語言
單調遞減棧
// 單調遞減棧: 尋找該柱子左右兩側第一個小于該柱子高度的柱子, 即可找到最后左右兩側最遠一個大于該柱子高度的連續柱子, 計算所形成的的最大面積
// 棧頂到棧底,元素依次遞減int minFun(int p1, int p2)
{return p1 < p2 ? p1 : p2;
}int maxFun(int p1, int p2)
{return p1 > p2 ? p1 : p2;
}int largestRectangleArea(int* heights, int heightsSize) {int stack[heightsSize];int top = 0;int maxSum = 0;// 遍歷for (int i = 0; i < heightsSize; i++) {// 尋找查找棧頂柱子的右側第一個低于棧頂柱子的柱子位置while (top > 0 && heights[i] < heights[stack[top - 1]]) {// 彈出棧頂元素int midIndex = stack[top - 1];top--;// 計算彈出元素所形成的凸型的面積// 判斷是否形成凸的最左側int leftIndex = 0;if (top > 0) {leftIndex = stack[top - 1] + 1;}int rightIndex = i - 1;int sum = heights[midIndex] * (rightIndex - leftIndex + 1);maxSum = maxFun(maxSum, sum);}stack[top] = i;top++;}// 判斷是否最后沒有形成凸的最右側,清空棧while (top > 0){int midIndex = stack[top - 1];top--;if (top == 0) {// 此時這個元素為當前元素數組中最小的元素int sum = heights[midIndex] * heightsSize;maxSum = maxFun(maxSum, sum);} else {// 此時單調棧中元素遞減int sum = heights[midIndex] * ((heightsSize - 1) - (stack[top - 1] + 1) + 1);maxSum = maxFun(maxSum, sum);}}return maxSum;
}

針對數組單調遞增等不能形成凸型的特殊情況, 需要特殊處理,
所以在原數組首尾添加最小元素0, 以便對原數組做同一處理。
優化代碼如下。

// 單調遞減棧: 尋找該柱子左右兩側第一個小于該柱子高度的柱子, 即可找到最后左右兩側最遠一個大于該柱子高度的連續柱子, 計算所形成的的最大面積
// 棧頂到棧底,元素依次遞減
// 針對數組單調遞增等的特殊情況, 需要特殊處理,所以在原數組首尾添加最小元素0,以便對原數組做同一處理int maxFun(int p1, int p2)
{return p1 > p2 ? p1 : p2;
}int largestRectangleArea(int* heights, int heightsSize) {int newHeightsSize = heightsSize + 2;int newHeights[newHeightsSize];newHeights[0] = 0;newHeights[newHeightsSize - 1] = 0;for (int t = 1; t < newHeightsSize - 1; t++) {newHeights[t] = heights[t - 1];}int stack[newHeightsSize];int top = 0;int maxSum = 0;// 遍歷for (int i = 0; i < newHeightsSize; i++) {// 尋找查找棧頂柱子的右側第一個低于棧頂柱子的柱子位置// 當遍歷到新數組的最后一個元素0, 必可以進入該循環進行處理while (top > 0 && newHeights[i] < newHeights[stack[top - 1]]) {// 彈出棧頂元素int midIndex = stack[top - 1];top--;// 計算彈出元素所形成的凹型的面積// 此處的棧中必有新數組的首元素0int leftIndex = stack[top - 1] + 1;int rightIndex = i - 1;int sum = newHeights[midIndex] * (rightIndex - leftIndex + 1);maxSum = maxFun(maxSum, sum);}stack[top] = i;top++;}return maxSum;
}
雙指針

尋找該柱子左側的第一個小于該柱子的高度的下標minLeftIndex[i] 和 右側第一個小于該柱子的高度的下標minRightIndex[i],
進而計算不小于該柱子高度的連續長度。

// 雙指針方法: 尋找該柱子左側的第一個小于該柱子的高度的下標minLeftIndex[i] 和 右側第一個小于該柱子的高度的下標minRightIndex[i]
// 計算以當前柱子形成凹形狀的柱子的最大面積int minFun(int p1, int p2)
{return p1 < p2 ? p1 : p2;
}int maxFun(int p1, int p2)
{return p1 > p2 ? p1 : p2;
}int largestRectangleArea(int* heights, int heightsSize) {int minLeftIndex[heightsSize];int minRightIndex[heightsSize];// 遍歷,尋找該柱子左側的第一個小于該柱子的高度的下標minLeftIndex[0] = -1;for (int i = 1; i < heightsSize; i++) {int t = i - 1;// 查找左側第一個小于該柱子高度的柱子下標while (t >= 0 && heights[t] >= heights[i]) {t = minLeftIndex[t];}minLeftIndex[i] = t;}// 遍歷,尋找該柱子右側的第一個小于該柱子的高度的下標minRightIndex[heightsSize - 1] = heightsSize;for (int j = heightsSize - 2; j >= 0; j--) {int t = j + 1;// 查找右側第一個小于該柱子高度的柱子下標while (t < heightsSize && heights[t] >= heights[j]) {t = minRightIndex[t];}minRightIndex[j] = t;}// 遍歷尋找最大面積int sum = 0;int maxSum = 0;for (int k = 0; k < heightsSize; k++) {// 求以當前柱子形成凹形狀的柱子的最大面積int leftIndex = minLeftIndex[k] + 1;int rightIndex = minRightIndex[k] - 1;sum = heights[k] * (rightIndex - leftIndex + 1);maxSum = maxFun(maxSum, sum);}return maxSum;
}

今日收獲

  1. 單調棧,以及為了使用單調棧所做的變化

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/39655.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/39655.shtml
英文地址,請注明出處:http://en.pswp.cn/web/39655.shtml

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

相關文章

分治求解最大子數組

分治求解最大子數組 分治求解步驟 分&#xff1a;將數組分成左右兩部分治&#xff1a;遞歸地求解左半部分和右半部分的最大子數組合&#xff1a;計算跨越中點的最大子數組&#xff0c;并取三者中的最大值 具體實現 分&#xff1a; 將數組A分成兩部分 左半部分&#xff1a;從…

專業的TPM管理咨詢公司有哪些特點?

專業的TPM管理咨詢公司&#xff0c;作為現代企業管理和設備維護的重要合作伙伴&#xff0c;其特點不僅體現在技術能力和服務質量上&#xff0c;更在于其獨特的經營理念和方法論。以下是專業TPM管理咨詢公司所具備的顯著特點&#xff1a; 一、全面的技術實力與深厚的行業經驗 專…

迎接AI時代的新篇章:GPT-5 技術突破與未來展望

GPT-5 一年半後發布&#xff1f;對此你有何期待&#xff1f; 前言 在美國達特茅斯工程學院的一次採訪中&#xff0c;OpenAI 首席技術官米拉穆拉蒂透露&#xff0c;GPT-5 將在一年半後發布&#xff0c;並將其描述為從高中生智力水平躍升到博士生水平的飛躍。這一消息在科技界引…

Lambda表達式講解

簡介: Lambda表達式的使用場景非常廣泛,主要包括函數式編程、集合操作、排序、線程編程、GUI事件處理、數據處理、Web開發等。 函數式編程:Lambda表達式是函數式編程的重要特性,可以用于替代傳統的匿名內部類,簡化代碼,提高可讀性。 集合操作:Lambda表達式可以與集合…

word 轉pdf 中圖片不被壓縮的方法

word 轉pdf 中圖片不被壓縮的方法 法1&#xff1a; 調節word 選項中的圖片格式為不壓縮、高保真 法2&#xff1a; 1: word 中的圖片盡可能使用高的分辨率&#xff0c;圖片存為pnd或者 tif 格式&#xff08;最高清&#xff09; 2: 轉化為pdf使用打印機器&#xff0c;參數如下…

展開說說:Android四大組件之Service使用

Service一定要開啟子線程才可以執行耗時任務嗎&#xff1f;不完全是吧。 Service是Android系統中的四大組件之一&#xff0c;它是一種沒有可視化界面&#xff0c;運行于后臺的一種服務程序。屬于計算型組件&#xff0c;用來在后臺執行持續性的計算任務&#xff0c;重要性僅次于…

分子AI預測賽筆記

#AI夏令營 #Datawhale #夏令營 Taks1 跑通baseline 根據task1跑通baseline 注冊賬號 直接注冊或登錄百度賬號&#xff0c;etc fork 項目 零基礎入門 Ai 數據挖掘競賽-速通 Baseline - 飛槳AI Studio星河社區 啟動項目 選擇運行環境&#xff0c;并點擊確定&#xff0c;沒…

臺燈學生用哪個牌子最好?學生用臺燈品牌排行榜分析

臺燈學生用哪個牌子最好&#xff1f;護眼臺燈在近年來成為家長和長時間使用電子設備人群關注的家電/學生產品。對于家中有孩子或經常面對電子屏幕的人士來說&#xff0c;很多人可能已經對這類產品有所了解并進行了購買。然而&#xff0c;部分家長對護眼臺燈的認識還不夠深入&am…

不同類型uORF對mORF翻譯效率的影響

在您提供的文獻《不同類型的uORF在真核生物基因表達中的調控潛力》中&#xff0c;對于不同類型的起始密碼子的uORF及其對下游主開放閱讀框&#xff08;mORF&#xff09;翻譯效率的影響進行了詳細的討論。以下是這些影響的主要總結&#xff1a; uORF的起始密碼子類型&#xff1a…

FFT 簡單基礎(matlab

使用 fs 進行采樣&#xff0c;進行 N點FFT 選擇顯示0~N/21點的幅值 橫坐標對應頻率計算公式&#xff1a; fs * n / N 舉個梨子&#xff1a; 頻率2kHz采樣1s&#xff0c;得到2000個點的序列y(n) 對序列y(n)做4096點的FFT 幅值響應對應的橫坐標頻率…

機器人控制系列教程之Stewart平臺簡介和運動學分析

Stewart平臺簡介及應用場景 六自由度 Stewart 并聯機器人結構簡圖如下圖所示&#xff0c;主要有一個固定平臺和一個移動平臺以及六個可伸縮的推桿組成&#xff0c;通常情況下&#xff0c;固定平臺與底座連接&#xff0c;移動平臺在空間具有六個自由度&#xff0c;通過六個推桿…

數據結構——求兩個數的最大公因子

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> 數據結構——求兩個數的最大公因子 要求&#xff1a;必須采用遞歸和非遞歸兩種方法 非遞歸&#xff1a; int main() { int a 0; int b 0; scanf("%d %d", &a, &b); int c a…

攻防演練,怎么掃描一個網站

在 Ubuntu 22.04 上&#xff0c;你可以使用多種掃描工具來進行網站掃描。以下是一些常見的掃描工具以及它們的安裝方法&#xff1a; Nmap: Nmap 是一個開源的網絡掃描工具&#xff0c;用于發現網絡和安全審計。安裝命令&#xff1a;sudo apt update sudo apt install nmapNikto…

價格很實惠,希喂、愛立方、生生不息主食凍干抗得住實測嗎?

在挑選主食凍干時&#xff0c;許多寵物主人都會感到頭疼。盡管主食凍干相較于普通貓糧具有諸多優勢&#xff0c;但其價格也相對高昂。這導致許多寵物主人擔心高價購買的主食凍干可能營養價值并不理想。然而&#xff0c;在選擇時&#xff0c;我們還需要考慮其他重要因素&#xf…

Spring MVC 中 使用 RESTFul 實現用戶管理系統

1. Spring MVC 中 使用 RESTFul 實現用戶管理系統 文章目錄 1. Spring MVC 中 使用 RESTFul 實現用戶管理系統2. 靜態頁面準備2.1 user.css2.2 user_index.html2.3 user_list.html2.4 user_add.html2.5 user_edit.html 3. SpringMVC環境搭建3.1 創建module&#xff1a;usermgt3…

tapd 與國內外主流的8大項目管理軟件大對比

對比Tapd與8大項目管理工具&#xff1a;PingCode、Worktile、Redmine、Teambition、廣聯達、Jira、禪道、飛書。 Tapd 是騰訊推出的一款敏捷開發管理工具&#xff0c;特別適合那些需要高效協作和快速迭代的敏捷開發團隊。它支持多種敏捷方法論&#xff0c;包括Scrum和Kanban&am…

《詳細指南:本地部署Ollama大型模型的完整步驟》

《詳細指南&#xff1a;本地部署Ollama大型模型的完整步驟》 引言 Ollama是一個高性能的AI模型部署平臺&#xff0c;支持在本地輕松部署大型語言模型。本指南將詳細介紹如何在本地環境中部署Ollama&#xff0c;并運行一個大型模型。 環境要求 操作系統&#xff1a;Windows/…

數學建模------Matlab數據可視化

目錄 1.plot函數 &#xff08;1&#xff09;函數介紹 &#xff08;2&#xff09;參數介紹 &#xff08;3&#xff09;圖形美化 &#xff08;4&#xff09;背景更改 &#xff08;5&#xff09;多組繪制 &#xff08;6&#xff09;圖形疊加 &#xff08;7&#xff09;添加…

Elasticsearch備份數據到本地,并導入到新的服務 es 服務中

文章目錄 使用elasticsearch-dump工具備份安裝node.js(二進制安裝)解壓設置環境變量安裝elasticsearch-dump docker安裝使用ES備份文件到本地 使用elasticsearch-dump工具備份 這個工具備份時間比較長 安裝node.js(二進制安裝) wget https://nodejs.org/dist/v16.18.0/node-…

C語言 求分數序列的和

求分數序列2/1&#xff0c;3/2&#xff0c;5/3&#xff0c;8/5&#xff0c;13/8&#xff0c;21/13…。求出數列的n項和&#xff0c;n由鍵盤輸入&#xff0c;并計算n20的結果 這個程序計算分數序列的前 n 項和&#xff0c;并輸出 n 20 時的結果。 #include <stdio.h>in…