一魚多吃 用水槽模型 解 最多的雨水儲存量 Trapping Rain Water Leetcode #42

更新於 發佈於 閱讀時間約 5 分鐘
raw-image

這題的題目在這裡:

題目敘述

題目會給我們一個陣列,陣列裡面每個數字分別代表高低各不同的隔板高度,問我們從降雨之後,最多可以儲存多少水量?


測試範例

Example 1:

範例一的圖解

範例一的圖解

Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.
藍色部分的方格,代表可以儲存雨水的格子點。​

Example 2:

Input: height = [4,2,0,3,2,5]
Output: 9

約束條件

Constraints:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

演算法

其實這一題和前面學過的水槽模型裝水那一題九成像。

都是給我們隔板高度,要求我們計算最多可以儲存的水量是多少?

差別在於:

前一題的水槽底部是平的

這一題的水槽底部高低不同,有凹有凸。

但是,最關鍵的核心精神相同,可以裝的水量多寡由比較矮的隔板決定

(因為水只要超過比較矮的那一邊就會溢出去,就算再下雨注入水也
無法儲存更多了。)


因此,我們只要建立一個滑窗,每次在水平方向移動一格收縮比較矮的一邊

如果左邊的隔板比右邊矮,就收縮左邊。

如果右邊的隔板比左邊矮,就收縮右邊。

每次迭代的時候,同步更新累加
當下可以儲存的水量 = 比較矮的隔板高度 - 水槽底部高度
(相當於二維平面上投影的面積,就像範例圖中的樣子)

最後,回傳能儲存雨水的總面積,就是答案。


程式碼

class Solution:
 def trap(self, height: List[int]) -> int:
  
  if len(height) < 3:
   
   # Quick response for impossible cases
   return 0
  
  volume, size = 0, len(height)
  
  # two pointers, initialized as boundary index
  left, right = 0, size-1
  
  # local max height on two sides
  left_wall_max, right_wall_max = height[left], height[right]
  
  # scan each index with two-pointers
  while left < right:
   
   # update local max height
   left_wall_max, right_wall_max = max(height[left], left_wall_max), max(height[right], right_wall_max)
   
   
   if left_wall_max <= right_wall_max:
    
    # left wall is shorter than right wall
    
    # update trapping rain water of current index
    volume += left_wall_max - height[left]
    
    # move left pointer to right hand side
    left += 1
    
   else:
    
    # right wall is shorter than left wall
    
    # update trapping rain water of current index
    volume += right_wall_max - height[right]
    
    # move right pointer to left hand side
    right -= 1
    
  
  return volume

複雜度分析

時間複雜度:

O( n ) 收縮滑窗,滑窗寬度從n-1 收縮到 1,總共耗費O(n)的時間

空間複雜度:

O(1) 都是臨時變數,所占用的記憶體空間固定,都是常數級別O(1)


關鍵知識點

這一題用到的也是水槽裝水的模型,唯一的小差別就是多了水槽底部有了高度,但是核心精神不變: 可以裝的水量多寡由比較矮的隔板決定

強烈建議複習Container With Most Water這一題,
鞏固 水槽裝水的模型雙指針應用的知識點


Reference:

[1] Python O(n) by two-pointers // DP [w/ Hint] - Trapping Rain Water - LeetCode

留言
avatar-img
留言分享你的想法!
avatar-img
小松鼠的演算法樂園
96會員
427內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
2024/10/06
題目敘述 Rank Transform of an Array 給定一個陣列arr,請根據數字的大小給予序號,序號值介於1~len( set(arr) )之間。 最大的數字給予最大的序號。 次大的數字給予次大的序號。 ...依此類推 最小的數字給予最小的序號1。
Thumbnail
2024/10/06
題目敘述 Rank Transform of an Array 給定一個陣列arr,請根據數字的大小給予序號,序號值介於1~len( set(arr) )之間。 最大的數字給予最大的序號。 次大的數字給予次大的序號。 ...依此類推 最小的數字給予最小的序號1。
Thumbnail
2024/10/01
題目敘述 Check If Array Pairs Are Divisible by k 給定一個長度為偶數的整數陣列arr,和一個整數k 。 我們想把陣列元素兩兩一組組成pair,使得每個pair的總和可以被k整除。 如果做得到,返回True。 如果不行,返回False。
Thumbnail
2024/10/01
題目敘述 Check If Array Pairs Are Divisible by k 給定一個長度為偶數的整數陣列arr,和一個整數k 。 我們想把陣列元素兩兩一組組成pair,使得每個pair的總和可以被k整除。 如果做得到,返回True。 如果不行,返回False。
Thumbnail
2024/09/29
My Calendar II 給定一個行事曆的class定義和行程安排的介面。 請完成下列function 1.建構子MyCalendarTwo() 2.boolean book(int start, int end) 在行事曆加入一項新行程,起始時間為start, 結束時間為end。
Thumbnail
2024/09/29
My Calendar II 給定一個行事曆的class定義和行程安排的介面。 請完成下列function 1.建構子MyCalendarTwo() 2.boolean book(int start, int end) 在行事曆加入一項新行程,起始時間為start, 結束時間為end。
Thumbnail
看更多
你可能也想看
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
2025 vocus 推出最受矚目的活動之一——《開箱你的美好生活》,我們跟著創作者一起「開箱」各種故事、景點、餐廳、超值好物⋯⋯甚至那些讓人會心一笑的生活小廢物;這次活動不僅送出了許多獎勵,也反映了「內容有價」——創作不只是分享、紀錄,也能用各種不同形式變現、帶來實際收入。
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
給定一個整數數組 height,每個元素表示一個柱子的高度,其中每個柱子的寬度為 1,請計算柱子之間可以容納多少雨水。
Thumbnail
給定一個整數數組 height,每個元素表示一個柱子的高度,其中每個柱子的寬度為 1,請計算柱子之間可以容納多少雨水。
Thumbnail
子集合生成是一道經典的組合類上機考和面試題目。本篇文章介紹多個不同的解決方案,以及相關演算法框架。主要目標是給定n個相異的元素,產生所有的子集合。
Thumbnail
子集合生成是一道經典的組合類上機考和面試題目。本篇文章介紹多個不同的解決方案,以及相關演算法框架。主要目標是給定n個相異的元素,產生所有的子集合。
Thumbnail
題目敘述 題目會給我們一個隔板陣列height,代表每個隔板的高度,讓我們選取兩個隔板作為水槽的邊界,請問最多我們能裝多少水? 題目的原文敘述 測試範例 Example 1: Input: height = [1,8,6,2,5,4,8,3,7] Output: 49 Explanati
Thumbnail
題目敘述 題目會給我們一個隔板陣列height,代表每個隔板的高度,讓我們選取兩個隔板作為水槽的邊界,請問最多我們能裝多少水? 題目的原文敘述 測試範例 Example 1: Input: height = [1,8,6,2,5,4,8,3,7] Output: 49 Explanati
Thumbnail
這題也算是Leetcode 上經典的DP考題之一,也是很好的DP邏輯思考練習題。 題目敘述 題目會給我們一個nums陣列,分別代表每棟房屋的價值,也就是房屋內有的現金數量。 題目敘述給的情境是假想盜賊要偷東西,限制是相鄰的兩棟房屋不能一起偷,只能選擇其中一棟,否則就會觸發警報器。 請問怎麼選
Thumbnail
這題也算是Leetcode 上經典的DP考題之一,也是很好的DP邏輯思考練習題。 題目敘述 題目會給我們一個nums陣列,分別代表每棟房屋的價值,也就是房屋內有的現金數量。 題目敘述給的情境是假想盜賊要偷東西,限制是相鄰的兩棟房屋不能一起偷,只能選擇其中一棟,否則就會觸發警報器。 請問怎麼選
Thumbnail
題目敘述 題目會給我們一個二維陣列matrix,分別代表每個格子的成本,請問我們從最頂端到底部的下墜路徑的最小成本總和是多少? 每次下墜到下一排的時候,可以有三種選擇: 1.往左下角移動。 2.往正下方移動。 3.往右下角移動。 題目的原文敘述 測試範例 Example 1:
Thumbnail
題目敘述 題目會給我們一個二維陣列matrix,分別代表每個格子的成本,請問我們從最頂端到底部的下墜路徑的最小成本總和是多少? 每次下墜到下一排的時候,可以有三種選擇: 1.往左下角移動。 2.往正下方移動。 3.往右下角移動。 題目的原文敘述 測試範例 Example 1:
Thumbnail
題目會給我們一個山形的輸入陣列,和目標值target,要求我們找出目標值所在的陣列索引。如果出現兩次,返回比較小的那一個,也就是比較靠左的那個索引值。 山形的意思就是說,從最左側到山頂最大值都是遞增,從山頂最大值到右側都是遞減。
Thumbnail
題目會給我們一個山形的輸入陣列,和目標值target,要求我們找出目標值所在的陣列索引。如果出現兩次,返回比較小的那一個,也就是比較靠左的那個索引值。 山形的意思就是說,從最左側到山頂最大值都是遞增,從山頂最大值到右側都是遞減。
Thumbnail
題目會給一個輸入陣列,裡面的數字分別代表每個index對應到的高度,要求我們計算山峰與低谷的數目,總共有多少個。 山峰 Hill: 比最靠近高度不相同的兩個鄰居的高度還要高。 低谷 Valley:比最靠近高度不相同的兩個鄰居的高度還要低。
Thumbnail
題目會給一個輸入陣列,裡面的數字分別代表每個index對應到的高度,要求我們計算山峰與低谷的數目,總共有多少個。 山峰 Hill: 比最靠近高度不相同的兩個鄰居的高度還要高。 低谷 Valley:比最靠近高度不相同的兩個鄰居的高度還要低。
Thumbnail
題目會給我們一個陣列,分別代表高低各不同的隔板高度,問我們從降雨之後,最多可以儲存多少水量?
Thumbnail
題目會給我們一個陣列,分別代表高低各不同的隔板高度,問我們從降雨之後,最多可以儲存多少水量?
Thumbnail
題目會給定一個陣列,陣列裡面的元素分布就像一座山峰。 最大值的左邊都是上坡段,最大值的右邊都是下坡段。 要求我們找出陣列裡面的絕對極大值(absolute max value)所在的陣列索引
Thumbnail
題目會給定一個陣列,陣列裡面的元素分布就像一座山峰。 最大值的左邊都是上坡段,最大值的右邊都是下坡段。 要求我們找出陣列裡面的絕對極大值(absolute max value)所在的陣列索引
Thumbnail
題目會給定一個陣列,裡面有大有小,可以把數字的大小類比成高度 要求我們找出陣列裡面的相對極大值(relative max value)所在的陣列索引 也就是說當下這個元素,大於左邊鄰居的元素值,也大於右邊鄰居的元素值
Thumbnail
題目會給定一個陣列,裡面有大有小,可以把數字的大小類比成高度 要求我們找出陣列裡面的相對極大值(relative max value)所在的陣列索引 也就是說當下這個元素,大於左邊鄰居的元素值,也大於右邊鄰居的元素值
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News