LeetCode42接雨水問題

LeetCode42

在這裏插入圖片描述
首先,單獨來看每一個柱子,每一個柱子上邊能乘的雨水和三個東西有關係。左邊的最大值和右邊的最大值和自己的高度。用公式來表示就是:

curWater = Min(lMax, rMax) - curHeight

思路清晰了之後,這道題有很多解法。比如比較麻煩的方法先遍歷一遍找出最大值,之後在最大值左邊和右邊遍歷。最大值左邊的rMax就是這個最大值。這種方法需要遍歷兩遍。不是最優解。

還有一種方法是可以遍歷一遍就出結果的。那就是單調棧。

單調棧就是維護一個“頭重腳輕“的棧。如果有大於棧頂的元素進入則說明可以乘住雨水了。把小於當前元素的都pop出來。

棧中存儲的是數組元素的index。代碼如下:

public class Solution {
    public int trap(int[] height) {
        int res = 0;
        if (height == null) {
            return 0;
        }
        int len = height.length;
        // 單調棧
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < len; i++) {
            // 如果不單調的話那就持續pop
            while (!stack.empty() && height[stack.peek()] < height[i]) {
                Integer curIdx = stack.pop();
                // 如果棧頂元素一直相等,那麼全都pop出去,只留第一個。
                while (!stack.isEmpty() && height[stack.peek()] == height[curIdx]) {
                    stack.pop();
                }
                // 獲取棧數據的時候總要看是否爲空
                if (!stack.empty()) {
                    Integer left = stack.peek();
                    res += (Math.min(height[left], height[i]) - height[curIdx]) * (i - left - 1);
                }
            }
            // 單調的話就繼續push
            stack.push(i);
        }
        return res;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章