[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.

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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM