代码随想录算法训练营 day 59: ● 503.下一个更大元素II ● 42. 接雨水

94 阅读2分钟

503. Next Greater Element II 数组环形寻找下一个更大的元素,头尾扫两遍即可。第二遍取下标的余数。

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        Deque<Integer> stk = new LinkedList<Integer>();
        int len = nums.length;
        int[] res = new int[len];
        Arrays.fill(res, -1);

        stk.push(0);
        boolean first = true;

        for(int i=1; i<len*2; i++) {
            int cur = i % len;
            if(nums[cur] <= nums[stk.peek()]) {
                stk.push(cur);
            }
            else {
                while(!stk.isEmpty() && nums[cur] > nums[stk.peek()]) {
                    res[stk.peek()] = nums[cur];
                    stk.pop();
                }

                stk.push(cur);
            }
        }

        return res;
    }
}

42. Trapping Rain Water 双指针感觉好做一点。用单调栈的话,要考虑三种情况

  • 情况一:当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[st.top()]
  • 情况二:当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[st.top()]
  • 情况三:当前遍历的元素(柱子)高度大于栈顶元素的高度 height[i] > height[st.top()]

如果当前遍历的元素(柱子)高度小于栈顶元素的高度,就把这个元素加入栈中,因为栈里本来就要保持从小到大的顺序(从栈头到栈底)。 如果当前遍历的元素(柱子)高度等于栈顶元素的高度,要跟更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。 如果当前遍历的元素(柱子)高度大于栈顶元素的高度,此时就出现凹槽了,那么雨水高度是 min(凹槽左边高度, 凹槽右边高度) - 凹槽底部高度,代码为:int h = min(height[st.top()], height[i]) - height[mid];

雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1(因为只求中间宽度),代码为:int w = i - st.top() - 1 ;

当前凹槽雨水的体积就是:h * w

class Solution {
    public int trap(int[] height) {
        Deque<Integer> stk = new LinkedList<Integer>();
        int sum = 0;
        int len = height.length;
        stk.push(0);

        for(int i=1; i<len; i++) {
            if(height[stk.peek()] > height[i]) {
                stk.push(i);
            }
            else if (height[stk.peek()] == height[i]){
                stk.pop();
                stk.push(i);
            }
            else {

                while(!stk.isEmpty() && height[stk.peek()] < height[i]) {
                    int mid = stk.peek();
                    stk.pop();

                    if(!stk.isEmpty()) {
                        int h = Math.min(height[stk.peek()], height[i]) - height[mid];
                        int w = i - stk.peek() - 1;
                        sum += (h * w);
                    }

                }

                stk.push(i);
            }
        }

        return sum;
    }
}