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.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

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!
問題: 給定一個數組,每個元素表示海報高度,每個元素寬度均為 1 ,求這個數組能裝多少雨水。
雖然這道題屬於 two pointers 類型,不過我是用借助隊列來解的。
可能是因為之前做過直方圖相關的題目Largest Rectangle in Histogram ,這道題做起來感覺思路挺順暢。將數組的值稱為泥土體積。
- 對於從左往右的遞增區間,裝滿雨水后的總體積 - 該區間的總泥土體積 = 該區間的總雨水
- 對於剩余的從右往左的遞增區間,同樣地,裝滿雨水后的總體積 - 該區間的總泥土體積 = 該區間的總雨水
對於題目中的例子而言,從左往右的遞增區間是 [0,1,0,2,1,0,1,3 ], 剩余的從右往左的遞增區間是 [ 3,2,1,2,1]。
class place{ public: int idx; int height; place(int idx, int height){ this->idx = idx; this->height = height; } }; int trap(vector<int>& height) { if(height.size() == 0){ return 0; } // 計算從左往右的遞增區間 queue<place*> qL; place* tmpp = new place(0, height[0]); qL.push(tmpp); for (int i = 1; i < height.size(); i++) { if (height[i] >= qL.back()->height) { place* tmpp = new place(i, height[i]); qL.push(tmpp); } } int totalRectL = 0; while (qL.size() > 1 ) { place* tmpp = qL.front(); qL.pop(); int len = qL.front()->idx - tmpp->idx; totalRectL += (tmpp->height * len); } place* heighestL = qL.front(); qL.pop(); int earthAmtL = 0 ; for (int i = 0 ; i < heighestL->idx; i++) { earthAmtL += height[i]; } int waterL = totalRectL - earthAmtL; // 計算剩余的從右往左的遞增區間 queue<place*> qR; tmpp = new place((int)height.size()-1,height[height.size()-1]); qR.push(tmpp); for (int i = (int)height.size()-2; i >= heighestL->idx; i--) { if (height[i] >= qR.back()->height) { tmpp = new place(i, height[i]); qR.push(tmpp); } } int rectR = 0; while (qR.size() > 1) { place* tmpp = qR.front(); qR.pop(); int len = tmpp->idx - qR.front()->idx; rectR += tmpp->height * len; } place* heighestR = qR.front(); qR.pop(); int earthAmtR = 0; for (int i = (int)height.size()-1; heighestR->idx < i ; i--) { earthAmtR += height[i]; } int waterR = rectR - earthAmtR; int res = waterL + waterR; return res; }
