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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

84. Largest Rectangle in Histogram

發(fā)布時(shí)間:2024/5/7 编程问答 66 豆豆
生活随笔 收集整理的這篇文章主要介紹了 84. Largest Rectangle in Histogram 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Title

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

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


以上是柱狀圖的示例,其中每個(gè)柱子的寬度為 1,給定的高度為 [2,1,5,6,2,3]。

圖中陰影部分為所能勾勒出的最大矩形面積,其面積為 10 個(gè)單位。

示例:

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

Solve

Violence

暴力的方法就比較好寫(xiě)了,直接枚舉矩形的寬和高,其中寬表示矩形貼著柱狀圖底邊的寬度,高表示矩形在柱狀圖上的高度。

雙重循環(huán)枚舉矩形的左右邊界以固定寬度w,高度為所有包含在內(nèi)柱子的最小高度h,對(duì)應(yīng)的面積為w * h:

def largestRectangleArea_Violence_Width(self, heights: List[int]) -> int:ans, length = 0, len(heights)for i in range(length):minHeight = max(heights)for j in range(i, length):minHeight = min(minHeight, heights[j])ans = max((j - i + 1) * minHeight, ans)return ans

還有一種暴力枚舉的方法,我們使用兩層循環(huán)枚舉寬,其實(shí)可以通過(guò)一層循環(huán)枚舉高,將其固定為矩形的高度h,然后從這根柱子開(kāi)始向兩側(cè)延伸,直到遇到高度小于h的柱子,就確定了矩形的左右邊界,即寬w,對(duì)應(yīng)的面積就是w * h:

def largestRectangleArea_Violence_Height(self, heights: List[int]) -> int:ans, length = 0, len(heights)for middle in range(length):height = heights[middle]left, right = middle, middlewhile left - 1 > -1 and heights[left - 1] >= height:left -= 1while right + 1 < length and heights[right + 1] >= height:right += 1ans = max(ans, (right - left + 1) * height)return ans

兩種暴力枚舉方法的時(shí)間復(fù)雜度均為O(N2),會(huì)超出時(shí)間顯示,枚舉寬度的方法使用了兩層循環(huán),沒(méi)有什么優(yōu)化的空間了,所以只能優(yōu)化枚舉高度的一層循環(huán)。

單調(diào)棧

如果有兩根柱子j0和j1,其中j0在j1的左側(cè),并且j0的高度大于等于j1,那么在后面的柱子i向左找小于其高度柱子時(shí),j1會(huì)擋住j0

這樣以來(lái),可以對(duì)數(shù)組從左向右進(jìn)行遍歷,同時(shí)維護(hù)一個(gè)可能答案的數(shù)據(jù)結(jié)構(gòu),其中按照從小到大的順序存放一些j值,如果我們存放了j0,j1,…,js,一定有heights[j0]<heights[j1]<…<heights[js]。

當(dāng)我們枚舉到第i根柱子時(shí),數(shù)據(jù)結(jié)構(gòu)中存放了j0,j1,…,js,如果第i根柱子左側(cè)且最近的小于其高度的柱子為ji,那么必然有:
height[j0]<height[j1]<?<height[ji]<height[i]≤height[ji+1]<?<height[js]height[j_0]<height[j_1]<?<height[j_i]<height[i]≤height[j_{i+1}]<?<height[j_s] height[j0?]<height[j1?]<?<height[ji?]<height[i]height[ji+1?]<?<height[js?]
當(dāng)我們枚舉到i+1時(shí),原來(lái)的i也變成了j值,因此i會(huì)被放入數(shù)據(jù)結(jié)構(gòu)。由于所有在數(shù)據(jù)結(jié)構(gòu)中的j值均小于i,那么所有高度大于等于height[i]的j都不會(huì)作為答案,需要從數(shù)據(jù)結(jié)構(gòu)中移除,恰好就是ji+1,…,js

這樣我們?cè)诿杜e到第 i 根柱子的時(shí)候,就可以先把所有高度大于等于 height[i] 的 j 值全部移除,剩下的 j 值中高度最高的即為答案。

在這之后,我們將 i 放入數(shù)據(jù)結(jié)構(gòu)中,開(kāi)始接下來(lái)的枚舉。此時(shí),我們需要使用的數(shù)據(jù)結(jié)構(gòu)也就呼之欲出了,它就是棧。

  • 棧中存放了 j 值。從棧底到棧頂,j 的值嚴(yán)格單調(diào)遞增,同時(shí)對(duì)應(yīng)的高度值也嚴(yán)格單調(diào)遞增;
  • 當(dāng)我們枚舉到第 i 根柱子時(shí),我們從棧頂不斷地移除 height[j]≥height[i] 的 j 值。在移除完畢后,棧頂?shù)?j 值就一定滿足 height[j]<height[i],此時(shí) j 就是 i 左側(cè)且最近的小于其高度的柱子。
    • 如果我們移除了棧中所有的 j 值,那就說(shuō)明 i 左側(cè)所有柱子的高度都大于 height[i],可以認(rèn)為 i 左側(cè)且最近的小于其高度的柱子在位置 j=-1,一根「虛擬」的、高度無(wú)限低的柱子。
  • 再將 ii 放入棧頂

棧中存放的元素具有單調(diào)性,這就是經(jīng)典的數(shù)據(jù)結(jié)構(gòu)「單調(diào)棧」了。

例子:[6,7,5,2,4,5,9,3]

初始時(shí)的棧為空。

6:因?yàn)闂榭?#xff0c;所以 6 左側(cè)的柱子是「哨兵」,位置為 -1。隨后我們將 6 入棧。

  • 棧:[6(0)]。(這里括號(hào)內(nèi)的數(shù)字表示柱子在原數(shù)組中的位置)

7:由于 6<7,因此不會(huì)移除棧頂元素,所以 6 左側(cè)的柱子是 7,位置為 0。隨后我們將 7 入棧。

  • 棧:[6(0), 7(1)]

5:由于 7≥5,因此移除棧頂元素 7。同樣地,6≥5,再移除棧頂元素 6。此時(shí)棧為空,所以 5 左側(cè)的柱子是「哨兵」,位置為 ?1。隨后我們將 5 入棧。

  • 棧:[5(2)]

2:移除棧頂元素 5,得到 2 左側(cè)的柱子是「哨兵」,位置為 ?1。將 2 入棧。

  • 棧:[2(3)]

4,5 和 9:不會(huì)移除任何棧頂元素,得到它們左側(cè)的柱子分別是 2,4 和 5,位置分別為 3,4 和 5。將它們?nèi)霔!?/p>

  • 棧:[2(3), 4(4), 5(5), 9(6)]

3:依次移除棧頂元素 9,5 和 4,得到 3 左側(cè)的柱子是 2,位置為 3。將 3 入棧。

  • 棧:[2(3), 3(7)]

這樣以來(lái),我們得到它們左側(cè)的柱子編號(hào)分別為 [-1, 0, -1, -1, 3, 4, 5, 3]。用相同的方法,我們從右向左進(jìn)行遍歷,也可以得到它們右側(cè)的柱子編號(hào)分別為 [2, 2, 3, 8, 7, 7, 7, 8],這里我們將位置 8 看作「哨兵」。

每一個(gè)位置只會(huì)入棧一次(在枚舉到它時(shí)),并且最多出棧一次。因此當(dāng)我們從左向右/總右向左遍歷數(shù)組時(shí),對(duì)棧的操作的次數(shù)就為 O(N)。所以單調(diào)棧的總時(shí)間復(fù)雜度為 O(N)。

Code

def largestRectangleArea_MonotoneStack(self, heights: List[int]) -> int:length = len(heights)left, right = [0] * length, [0] * lengthmonotoneStack = list()for i in range(length):while monotoneStack and heights[monotoneStack[-1]] >= heights[i]:monotoneStack.pop()left[i] = monotoneStack[-1] if monotoneStack else -1monotoneStack.append(i)monotoneStack = list()for i in range(length - 1, -1, -1):while monotoneStack and heights[monotoneStack[-1]] >= heights[i]:monotoneStack.pop()right[i] = monotoneStack[-1] if monotoneStack else lengthmonotoneStack.append(i)ans = max((right[i] - left[i] - 1) * heights[i] for i in range(length)) if length > 0 else 0return ans

總結(jié)

以上是生活随笔為你收集整理的84. Largest Rectangle in Histogram的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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

主站蜘蛛池模板: 亚洲欧美日韩高清 | 不卡一二三 | 黄色片网站免费观看 | 无码成人精品区在线观看 | 欧美精品一区二区三区四区五区 | 中文字幕福利视频 | 中文字幕人妻一区二区三区视频 | 妞干网这里只有精品 | 国产av一区精品 | 黄色网址在线播放 | 国产免费视频 | 中文字幕在线日韩 | 噼里啪啦动漫高清在线观看 | 国产aⅴ精品一区二区三区久久 | 91看片就是不一样 | 在线日韩一区二区 | 免费黄色视屏 | 精品人妻互换一区二区三区 | 学生调教贱奴丨vk | 中国免费观看的视频 | 亚洲成a人片在线www | 69xx欧美 | 日本美女逼 | 一级片免费观看视频 | 久热免费在线视频 | 国产伦理一区 | 中文字幕在线观看1 | 日韩欧美第一区 | 久久一区精品 | 伊伊综合网| 国产精品成人免费精品自在线观看 | 日本一区二区三区免费看 | 九九免费在线视频 | 国产xx在线观看 | 久久精品片 | 波多野结衣视频观看 | 日韩中文字幕免费 | 黄视频在线免费 | 久久99一区 | 麻豆911| 丝袜诱惑一区二区 | 一区二区三区视频在线免费观看 | 超碰免费公开 | 一级全黄少妇性色生活片 | 国产剧情在线视频 | 日韩av免费在线 | 香蕉国产在线 | 成人一级生活片 | 一区二区在线视频观看 | av成人天堂 | 少妇系列在线观看 | 日韩网站在线观看 | 波多野结衣视频网址 | 天堂在线精品 | 无码国产精品高潮久久99 | 国产在线视频二区 | 91极品蜜桃臀 | 国产男女猛烈无遮挡免费视频动漫 | 久久精品网址 | 最新视频–x99av | 精品人妻少妇一区二区三区 | 欧美日韩高清不卡 | 美女屁股无遮挡 | 伊人久久大香线蕉av一区 | 成人永久免费视频 | avt天堂网| 二十四小时在线更新观看 | 日韩在线第一区 | 少妇被爽到高潮动态图 | 国产精品免费网站 | 色婷婷av一区二区三区软件 | 黄色片网站在线观看 | 免费在线你懂的 | 国产精品无码免费在线观看 | 亚洲麻豆精品 | 亚洲少妇激情 | 婷婷成人综合 | 免费国产黄 | 91精品国产色综合久久不卡蜜臀 | 91麻豆网站 | 少妇色欲网 | 美女交配 | 亚洲精品国产无码 | 日韩欧 | 久久久久久精 | 爽爽影院在线免费观看 | 日韩簧片在线观看 | 处女朱莉第一次 | 中文字幕黑丝 | 欧美色图一区二区三区 | 国产人妻人伦精品1国产盗摄 | av中文字幕一区二区 | 亚洲片在线观看 | 琪琪午夜伦理影院7777 | 99亚洲国产精品 | 亚洲资源站 | 欧美一区永久视频免费观看 | 潘金莲三级野外 | 懂色av一区二区在线播放 |