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