1. 程式人生 > >LeetCode 題解:42. Trapping Rain Water

LeetCode 題解:42. Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. 在這裡插入圖片描述 The above elevation map 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. Thanks Marcos for contributing this image!

Example: Input: [0,1,0,2,1,0,1,3,2,1,2,1] Output: 6

解題思路

用一個棧記錄遍歷過的關鍵位置,將陣列進行兩次遍歷即可得到答案。

  1. 第一次從左往右遍歷陣列:首先將下標0新增到棧中作為初始關鍵節點,然後從1開始遍歷。當height[i] >= height[top] (其中top代表棧頂儲存的下標位置)時,說明 i 和 top 之間存在空間能夠存放雨水。此時對子區間(top, i)進行遍歷,統計出這段子區間中的空白區。重複這一操作直到沒有找到 滿足 height[i] >= height[top] 的位置i。變數 rec 記錄當前棧頂儲存的位置 i。
  2. 第二次從右往左遍歷陣列:首先將下標height.size()-1新增到棧中作為初始關鍵節點,然後從height.size()-2開始遍歷,到 rec 結束。當height[i] >= height[top] (其中top代表棧頂儲存的下標位置)時,說明 i 和 top 之間存在空間能夠存放雨水。此時對子區間 (i, top) 進行遍歷,統計出這段子區間中的空白區。
  3. 將兩次統計出的空白區間相加就得到最後的結果。

C++程式碼

class Solution {
public:
    int trap(vector<int>& height) {
        stack<
int> pos; int sum = 0, rec = 0; pos.push(0); for(int i = 1; i < height.size(); i++) { if(height[i] >= height[pos.top()]) { for(int j = pos.top()+1; j < i; j++) { sum += height[pos.top()] - height[j]; } pos.push(i); } } rec = pos.top(); pos.push(height.size()-1); for(int i = height.size()-2; i >= rec; i--) { if(height[i] >= height[pos.top()]) { for(int j = pos.top()-1; j > i; j--) { sum += height[pos.top()] - height[j]; } pos.push(i); } } return sum; } };