1. 程式人生 > >Lintcode364 Trapping Rain Water II solution 題解

Lintcode364 Trapping Rain Water II solution 題解

DC 高度 開始 img 而且 jpeg 題解 c99 div

【題目描述】

Given n x m non-negative integers representing an elevation map 2d where the area of each cell is 1x1, compute how much water it is able to trap after raining.

技術分享圖片

給定n x m非負整數,表示二維的海拔地圖,每個單元的面積是1 x 1,計算下雨後能捕到多少水。

技術分享圖片

【題目鏈接】

www.lintcode.com/en/problem/trapping-rain-water-ii/

【題目解析】

首先我們應該能分析出,能裝水的底面肯定不能在邊界上,因為邊界上的點無法封閉,那麽所有邊界上的點都可以加入queue,當作BFS的啟動點,同時我們需要一個二維數組來標記訪問過的點,訪問過的點我們用紅色來表示,那麽如下圖所示:

技術分享圖片

我們再想想,怎麽樣可以成功的裝進去水呢,是不是周圍的高度都應該比當前的高度高,形成一個凹槽才能裝水,而且裝水量取決於周圍最小的那個高度,有點像木桶原理的感覺,那麽為了模擬這種方法,我們采用模擬海平面上升的方法來做,我們維護一個海平面高度mx,初始化為最小值,從1開始往上升,那麽我們BFS遍歷的時候就需要從高度最小的格子開始遍歷,那麽我們的queue就不能使用普通隊列了,而是使用優先級隊列,將高度小的放在隊首,最先取出,這樣我們就可以遍歷高度為1的三個格子,用綠色標記出來了,如下圖所示:

技術分享圖片

向周圍BFS搜索的條件是不能越界,且周圍格子未被訪問,那麽可以看出上面的第一個和最後一個綠格子無法進行進一步搜索,只有第一行中間那個綠格子可以搜索,其周圍有一個灰格子未被訪問過,將其加入優先隊列queue中,然後標記為紅色,如下圖所示:

技術分享圖片

那麽優先隊列queue中高度為1的格子遍歷完了,此時海平面上升1,變為2,此時我們遍歷優先隊列queue中高度為2的格子,有3個,如下圖綠色標記所示:

技術分享圖片

我們發現這三個綠格子周圍的格子均已被訪問過了,所以不做任何操作,海平面繼續上升,變為4,遍歷所有高度為4的格子,如下圖綠色標記所示:

技術分享圖片

由於我們沒有特別聲明高度相同的格子在優先隊列queue中的順序,所以應該是隨機的,其實誰先遍歷到都一樣,對結果沒啥影響,我們就假設第一行的兩個綠格子先遍歷到,那麽那麽周圍各有一個灰格子可以遍歷,這兩個灰格子比海平面低了,可以存水了,把存水量算出來加入結果res中,如下圖所示:

技術分享圖片

上圖中這兩個遍歷到的藍格子會被加入優先隊列queue中,由於它們的高度小,所以下一次從優先隊列queue中取格子時,它們會被優先遍歷到,那麽左邊的那個藍格子進行BFS搜索,就會遍歷到其左邊的那個灰格子,由於其高度小於海平面,也可以存水,將存水量算出來加入結果res中,如下圖所示:

技術分享圖片

等兩個綠格子遍歷結束了,它們會被標記為紅色,藍格子遍歷會先被標記紅色,然後加入優先隊列queue中,由於其周圍格子全變成紅色了,所有不會有任何操作,如下圖所示:

技術分享圖片

此時所有的格子都標記為紅色了,海平面繼續上升,繼續遍歷完優先隊列queue中的格子,不過已經不會對結果有任何影響了,因為所有的格子都已經訪問過了,此時等循環結束後返回res即可,

【參考答案】

www.jiuzhang.com/solutions/trapping-rain-water-ii/



Lintcode364 Trapping Rain Water II solution 題解