最大矩形問題

柱狀圖中最大的矩形

題目

分析

矩形的面積等于寬乘以高,因此只要能確定每個矩形的寬和高,就能計算它的面積。如果直方圖中一個矩形從下標為 i 的柱子開始,到下標為 j 的柱子結束,那么這兩根柱子之間的矩形(含兩端的柱子)的寬是 j-i+1,矩形的高就是兩根柱子之間的所有柱子最矮的高度。

暴力解法(不可取)

? ? ? ? 如果能逐一找出直方圖中所有矩形并比較它們的面積,就能夠得到最大矩形的面積。方法為:采用嵌套的二重循環遍歷所有矩形,并比較他們的面積。該種方法的時間復雜度為O(N^2),根據題目所給的提示可知,這種方法不能解決本題,會超時。

代碼為

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int n=heights.size();int maxarea=0;for(int i=0;i<n;i++){int minheight=heights[i];for(int j=i;j<n;j++){minheight=min(minheight,heights[j]);int area=minheight*(j-i+1);maxarea=max(maxarea,area);}}return maxarea;}
};
分治法(本題不可取)

? ? ? ? 仔細觀察直方圖可以發現,這個直方圖的最大矩形有3中可能:

第一種:矩形通過直方圖中最矮的柱子;

第二種:矩形的起始柱子和終止柱子都在直方圖中最矮柱子的左側;

第三種:矩形的起始柱子和終止柱子都在直方圖中最矮柱子的右側。

第二種和第三種從本質上來說和求整個直方圖的最大矩形面積是同一個問題,可以用遞歸函數解決。

代碼為:

class Solution {
public:int largestRectangleArea(vector<int>& heights) {return helper(heights,0,heights.size()-1);}int helper(vector<int>& heights,int start,int end){if(start>end) return 0;else if(start==end) return heights[start];else{int minindex=start;for(int i=start+1;i<=end;i++){if(heights[i]<heights[minindex])minindex=i;}int area=(end-start+1)*heights[minindex];int left=helper(heights,start,minindex-1);int right=helper(heights,minindex+1,end);return max(area,max(left,right));}}
};
單調棧法(可取)

? ? ? ? 下面介紹一種非常高效,巧妙的解法。這種解法用一個棧保存直方圖的柱子,并且在棧中的柱子的高度是遞增排序的。為了方便計算矩陣的高度,棧中保存的是柱子在數組中的下標,可以根據下標得到柱子的高度。

? ? ? ? 這種解法的基本思想是確保保存在棧中的直方圖的柱子的敢賭是遞增排序的。假設從左到右逐一掃描數組中的每根柱子,如果當前柱子的高度大于位于棧頂柱子的高度,那么將該柱子的下標入棧;否則,將位于棧頂的柱子的下標出棧,并且計算以位于棧頂的柱子為頂的最大矩形的面積。【注意:此時出棧須滿足:棧不為空并且棧頂柱子的高度大于等于當前柱子的高度】

????????以某根柱子為頂的最大矩形,一定是從該柱子向兩側眼神知道遇到比它矮的柱子,這個最大矩形的高是該柱子的高,最大矩形的寬是兩側比它矮的柱子中間的間隔。

? ? ? ? 如果當前掃描到的柱子的高小于位于棧頂柱子的高,那么將位于棧頂的柱子的下標出棧,并且計算以位于棧頂的柱子為頂的最大矩形的面積。由于保存在棧中的柱子的高度是遞增排序的,因此棧中位于棧頂前面的一根柱子一定比位于棧頂的柱子矮,于是很容易就能找到位于棧頂的柱子兩側比它矮的柱子。

? ? ? ? 當計算以當前柱子為頂的最大矩形的面積時,如果棧中沒有柱子,那么意味著它左側的柱子都比它高,因此可以想象在下標為 -1 的位置有一根比它矮的柱子。

? ? ? ? 當掃描數組中所以柱子之后,棧中可能仍然剩余一些柱子。因此,需要注意將這些柱子的下標出棧并計算以它們為頂的最大矩形的面積。

? ? ? ? 在掃描完數組中所有的柱子之后,當計算以當前柱子為頂的最大矩形的面積時,說明它的右側沒有比它矮的柱子,如果一根柱子的右側有比它矮的柱子,那么當掃描到右側較矮柱子的時候他就已經出棧了。因此,可以想象下標為數組長度的位置有一根比它矮的柱子。

? ? ? ? 由于已經計算了以每根柱子為頂的最大矩形面積,因此比較這些矩形的面積就能得到脂肪圖中的最大矩形面積。

代碼為

class Solution {
public:int largestRectangleArea(vector<int>& heights) {int n=heights.size();stack<int> st;st.push(-1);int maxarea=0;for(int i=0;i<n;i++){while(st.top()!=-1 && heights[st.top()]>=heights[i]){int height=heights[st.top()];st.pop();int width=i-st.top()-1;maxarea=max(maxarea,height*width);}st.push(i);}while(st.top() != -1){int height=heights[st.top()];st.pop();int width=n-st.top()-1;maxarea=max(maxarea,height*width);}return maxarea;}
};
最大矩形

題目

分析

? ? ? ? 上一道題是關于最大矩形的,這道題也是關于最大矩形的,他們之間有沒有某種聯系?如果能從矩陣中找出直方圖,那么就能通過計算直方圖中的最大矩形面積來計算矩陣中的最大矩形面積。

? ? ? ? 直方圖是由排列在同一基線上的相鄰柱子組成的圖形,由于題目要求矩形中只包含數字1,因此將矩陣中上下相鄰的值為1的各自看成直方圖中的柱子,如果分別以矩陣的每行為基線,就可以得到若干行由數字1的格子組成的直方圖。如下圖所示:

對應的直方圖如下:

說明:(a)以矩陣第一行為基線的直方圖;(b)以矩陣第二行為基線的直方圖;(c)以矩陣第三行為基線的直方圖;(d)以矩陣第四行為基線的資方圖。

暴力解法(可取)
class Solution {
public:int maximalRectangle(vector<string>& matrix) {if(matrix.size()==0 || matrix[0].size()==0) return 0;int m=matrix[0].size();vector<int> v(m);int mxarea=0;for(string s:matrix){for(int i=0;i<m;i++){if(s[i]=='0') v[i]=0;else v[i]++;}mxarea=max(mxarea,maxarea(v));}return mxarea;}int maxarea(vector<int>& heights) {int n=heights.size();int maxarea=0;for(int i=0;i<n;i++){int minheight=heights[i];for(int j=i;j<n;j++){minheight=min(minheight,heights[j]);int area=minheight*(j-i+1);maxarea=max(maxarea,area);}}return maxarea;}
};
分治法(可取)
class Solution {
public:int maximalRectangle(vector<string>& matrix) {if(matrix.size()==0 || matrix[0].size()==0) return 0;int m=matrix[0].size();vector<int> v(m);int mxarea=0;for(string s:matrix){for(int i=0;i<m;i++){if(s[i]=='0') v[i]=0;else v[i]++;}mxarea=max(mxarea,maxarea(v));}return mxarea;}int maxarea(vector<int>& heights) {return helper(heights,0,heights.size()-1);}int helper(vector<int>& heights,int start,int end){if(start>end) return 0;else if(start==end) return heights[start];else{int minindex=start;for(int i=start+1;i<=end;i++){if(heights[i]<heights[minindex])minindex=i;}int area=(end-start+1)*heights[minindex];int left=helper(heights,start,minindex-1);int right=helper(heights,minindex+1,end);return max(area,max(left,right));}}
};
單調棧法(可取)
class Solution {
public:int maximalRectangle(vector<string>& matrix) {if(matrix.size()==0 || matrix[0].size()==0) return 0;int m=matrix[0].size();vector<int> v(m);int mxarea=0;for(string s:matrix){for(int i=0;i<m;i++){if(s[i]=='0') v[i]=0;else v[i]++;}mxarea=max(mxarea,maxarea(v));}return mxarea;}int maxarea(vector<int> v){stack<int> st;st.push(-1);int area=0;for(int i=0;i<v.size();i++){while(st.top()!=-1 && v[i]<=v[st.top()]){int height=v[st.top()];st.pop();int width=i-st.top()-1;area=max(area,height*width);}st.push(i);}while(st.top()!=-1){int height=v[st.top()];st.pop();int width=v.size()-st.top()-1;area=max(area,height*width);}return area;}
};

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

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

相關文章

能把試卷上的字消除的軟件有哪些?推薦三款好用的

能把試卷上的字消除的軟件有哪些&#xff1f;在數字化時代&#xff0c;我們越來越依賴科技手段來解決生活中的各種問題。其中&#xff0c;試卷上的字消除問題&#xff0c;就是一個備受關注的痛點。幸運的是&#xff0c;現在市面上已經出現了多款能夠輕松消除試卷上字跡的軟件&a…

力扣hot100:295. 數據流的中位數(兩個優先隊列維護中位數)

LeetCode&#xff1a;295. 數據流的中位數 這個題目最快的解法應該是維護中位數&#xff0c;每插入一個數都能快速得到一個中位數。 根據數據范圍&#xff0c;我們應當實現一個 O ( n l o g n ) O(nlogn) O(nlogn)的算法。 1、超時—插入排序 使用數組存儲&#xff0c;維持數…

【WEB自動化面試02--學習過程的問題及解決】

day01 1、報錯獲取不到瀏覽器二進制文件&#xff1a;需要指定瀏覽器路徑及驅動路徑。 第一次使用谷歌瀏覽器驅動&#xff0c;找不到二進制文件報錯&#xff1a; selenium.common.exceptions.WebDriverException: Message: unknown error: cannot find Chrome binary Stacktra…

短視頻矩陣源碼----如何做正規開發規則分享:

一、什么是SaaS化服務技術開發&#xff1f; &#xff08;短視頻矩陣系統是源頭開發的應該分為3個端口---- 總后臺控制端、總代理端口&#xff0c;總商戶后臺&#xff09; SaaS是軟件即服務&#xff08;Software as a Service&#xff09;的縮寫。它是一種通過互聯網提供軟件應…

Vue2(0基礎入門)

環境準備 安裝腳手架 vuecli: npm install -g vue/clivite: npm init vuelatest-g 全局安裝&#xff0c;任意目錄都可以使用vue腳本 進入目錄創建項目&#xff1a; 在目錄的終端輸入&#xff1a;vue ui安裝devtool(這個網頁是安裝好了自動跳轉的) 運行項目&#xff1a; …

代碼隨想錄第27天|貪心算法part1

455.分發餅干 先給孩子和餅干排序&#xff0c;每次選取一個最大的餅干給一個最大胃口的孩子&#xff0c;直到餅干分完或者遍歷完孩子 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(…

Vue3【三】 使用TS自己編寫APP組件

Vue3【三】 使用TS自己編寫APP組件 運行截圖 目錄結構 注意目錄層級 文件源碼 APP.vue <template><div class"app"><h1>你好世界!</h1></div> </template><script lang"ts"> export default {name:App //組…

JavaScript的核心語法

JavaScript JavaScript&#xff1a;JavaScript的組成&#xff1a;核心語法&#xff1a;Hello&#xff1a;變量&#xff1a;JS的基本數據類型&#xff1a;特殊點&#xff1a; 數組&#xff1a;流程控制語句&#xff1a;函數&#xff1a;函數的重載&#xff1a;函數的遞歸:預定義…

在 VSCode 中搭建 Flutter 開發環境并運行項目

要在 Visual Studio Code (VSCode) 中運行 Flutter 項目并啟動虛擬機&#xff08;例如 Android Emulator&#xff09;&#xff0c;可以按照以下步驟進行設置和操作&#xff1a; 一、安裝 Flutter 和 Dart 插件 安裝 Flutter SDK&#xff1a; 前往 Flutter 官網 下載并安裝 Flu…

離散數學答疑 3

&#xff5e;A&#xff1a;A的補集 有時候空集是元素&#xff0c;有時候就是純粹的空集 A-B的定義&#xff1a; 笛卡爾積&#xff1a; 求等價關系&#xff1a;先求劃分再一一列舉 不同劃分&#xff1a;分幾塊。一塊&#xff1a;兩塊&#xff1a;三塊&#xff1a;分別計算 Ix是…

自然語言處理(NLP)—— 主題建模

1. 主題建模的概念 主題建模&#xff08;Topic Modeling&#xff09;是一種用于發現文檔集合&#xff08;語料庫&#xff09;中的主題&#xff08;或稱為主題、議題、概念&#xff09;的統計模型。在自然語言處理和文本挖掘領域&#xff0c;主題建模是理解和提取大量文本數據隱…

【常用工具系列】Git 教程——從入門到大師

目錄 前言一、Git 基礎1-1、Git 簡介與安裝安裝 Git 1-2、 Git 工作流程1-3、 Git 配置與管理用戶配置查看配置 1-4、 Git 倉庫操作克隆倉庫推送更改拉取更新 1-5 Git 分支管理創建分支切換分支刪除分支解決沖突 二、 Git 進階2-0、 Git 標簽使用創建標簽查看標簽檢出標簽推送標…

「動態規劃」如何求最小路徑和?

64. 最小路徑和https://leetcode.cn/problems/minimum-path-sum/description/ 給定一個包含非負整數的m x n網格grid&#xff0c;請找出一條從左上角到右下角的路徑&#xff0c;使得路徑上的數字總和為最小。說明&#xff1a;每次只能向下或者向右移動一步。 輸入&#xff1a;…

《嵌入式系統導論》

計算題 已知位帶別名基地址為0x220000000,計算位于位帶區的0x200FFFFF地址的數據位7,計算它對應的位帶別名區地址。 別名地址=位帶別名基地址+字節偏移量x32+位號x4 別名地址=0x22000000+(0x200FFFFF -0x20000000)*32+7*4=0x220000807 分析如下基本定時器配置語句。 { ………

ctfshow-web入門-命令執行(web37-web40)

目錄 1、web37 2、web38 3、web39 4、web40 命令執行&#xff0c;需要嚴格的過濾 1、web37 使用 php 偽協議&#xff1a; ?cphp://input post 寫入我們希望執行的 php 代碼&#xff1a; <?php system(tac f*);?> 拿到 flag&#xff1a;ctfshow{5c555d9a-6f55…

Mongodb數組元素更新之使用$定位數組第一個元素

學習mongodb&#xff0c;體會mongodb的每一個使用細節&#xff0c;歡迎閱讀威贊的文章。這是威贊發布的第63篇mongodb技術文章&#xff0c;歡迎瀏覽本專欄威贊發布的其他文章。 閱讀了不少Mongodb的文章&#xff0c;也和同事交流過。Mongodb數組更新是比較難理解的地方&#x…

EXCEL多sheet添加目錄跳轉

EXCEL多sheet添加目錄跳轉 背景 excel中有幾十個sheet&#xff0c;點下方左右切換sheet太耗時&#xff0c;希望可以有根據sheet名超鏈接跳轉相應sheet&#xff0c;處理完后再跳回原sheet。 方案一 新建目錄sheet&#xff0c;在A1寫sheet名&#xff0c;右鍵選擇最下方超鏈接…

問題:材料題請點擊右側查看材料問題 查看材料 #學習方法#經驗分享#學習方法

問題&#xff1a;材料題請點擊右側查看材料問題 查看材料 A.Colleges may reduce their enrollment. B.Top universities become increasingly competitive. C.Universities become selective in student admission. D.Colleges invest less in academy and infrastructure…

Go 文件壓縮解壓

在Go語言中&#xff0c;archive/zip包提供了創建、讀取和解壓縮ZIP格式文件的功能。 一、創建ZIP文件并添加內容----壓縮 package mainimport ("archive/zip""bytes""fmt""io""log""os" )func main() {// 創建一…

el-input中change事件造成的坑

el-input中change事件造成的坑 一、change事件定義二、如果僅回車時候觸發 一、change事件定義 僅在輸入框失去焦點或用戶按下回車時觸發 二、如果僅回車時候觸發 <el-inputv-model.trim"questionInput"placeholder"請輸入你的問題&#xff0c;按回車發送&…