第十章 单调栈part02

50 阅读1分钟

503. Next Greater Element II

Given a circular integer array nums (i.e., the next element of nums[nums.length - 1] is nums[0]), return the next greater number for every element in nums.

The next greater number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, return -1 for this number.

题目:

  • 循环问题一般可以将相同的两份数组拼接,最后再截取。

代码:

lass Solution {
    public int[] nextGreaterElements(int[] nums) {
        int[] newNums = new int[nums.length * 2];
        for (int i = 0; i < newNums.length; i++) {
            newNums[i] = nums[i % nums.length];
        }
        int[] result = new int[nums.length];
        Deque<Integer> stack = new LinkedList<>();
        Arrays.fill(result, -1);
        for (int i = 0; i < newNums.length; i++) {
            while (!stack.isEmpty() && nums[stack.peekLast()] < newNums[i]) {
                result[stack.pollLast()] = newNums[i];
            }
            stack.addLast(i % nums.length);
        }
        return result;
    }
}

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 can trap after raining.

题目解析:

  • 双指针:找到每一列的左边最大值和右边最大值
  • 单调栈(递减): 每次弹出栈时,计算以该高度为底时的存水量(高度 * 宽度)

代码:
1. 双指针

class Solution {
    public int trap(int[] height) {
        int[] leftMax = new int[height.length];
        int[] rightMax = new int[height.length];
        leftMax[0] = height[0];
        rightMax[height.length - 1] = height[height.length -1];
        for (int i = 1; i < height.length; i++) {
            leftMax[i] = Math.max(leftMax[i - 1], height[i]);
            rightMax[height.length - 1 - i] = Math.max(rightMax[height.length - i], height[height.length - 1 - i]);
        }
        int value = 0;
        for (int i = 0; i < height.length; i++) {
            value += Math.min(leftMax[i], rightMax[i]) - height[i];
        }
        return value;
    }
}

2. 单调栈

class Solution {
    public int trap(int[] height) {
        Stack<Integer> stack = new Stack<>();
        int value = 0;
        for (int i = 0; i < height.length; i++) {
            while (!stack.isEmpty() && height[stack.peek()] < height[i]) {
                int midHeight = height[stack.pop()];
                if (!stack.isEmpty()) {
                    int w = i - stack.peek() - 1;
                    int h = Math.min(height[i], height[stack.peek()]) - midHeight;
                    value += w * h;
                }
            }
            stack.push(i);
        }
        return value;
    }
}