###### tags: `LeetCode` `Two Pointer` `Hard` # LeetCode #42 [Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/) ### (Hard) (Google的題目) 給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。 --- 解法1: 建立兩數組leftwall, rightwall儲存在i點時左右的牆高, 之後遍歷height計算height[i]能儲存的雨水量,為leftwall與rightwall中較低者減去height[i]。 ``` class Solution { public: int trap(vector<int>& height) { int n=height.size(); if(n){ vector<int>leftwall(n,0); vector<int>rightwall(n,0); int temp=height[0]; for(int i=0;i<height.size();i++){ leftwall[i]=max(temp,height[i]); temp=max(temp,height[i]); } temp=height[n-1]; for(int i=n-1;i>=0;i--){ rightwall[i]=max(temp,height[i]); temp=max(temp,height[i]); } int ans=0; for(int i=0;i<n;i++){ ans+=(min(rightwall[i],leftwall[i])-height[i]); } return ans; } return 0; } }; ``` --- 解法2: 使用two pointer分別指向左右, 當左邊高度高於右邊高度時, 不須考慮左牆(因為水只會從右邊漏), 持續修正右牆高度並同時計算右牆高度減去height[right]的雨水量並進行加總直到右牆高度高於左牆, 此時換成計算左牆高度減去height[left], 如此循環直到left>right, 即可得到全部雨水數。 ``` class Solution { public: int trap(vector<int>& height) { if(height.size()){ int left=0, right=height.size()-1; int maxl=height[left], maxr=height[right]; int tmp; int ans=0; while(right>left){ if(maxr>=maxl){ ans+=maxl-height[left]; maxl=max(maxl,height[++left]);//2 } else{ ans+=maxr-height[right]; maxr=max(maxr,height[--right]); } } return ans; } return 0; } }; ```