503.下一个更大元素II
思路:本题仍然是利用单调栈来寻找下一个更大数值的问题,只不过数组可以循环来寻找。我的解决方法是,将两个相同的数组拼接,然后利用单调栈来寻找就好了(寻找过程与昨天的每日温度类似)。
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] res = new int[nums.length];
Arrays.fill(res, -1);
Deque<Integer> stack = new LinkedList<>();
stack.push(0);
int[] nums2 = new int[nums.length + nums.length];
for (int i = 0; i < nums.length; i++) {
nums2[i] = nums[i];
nums2[i + nums.length] = nums[i];
}
for (int i = 1; i < nums2.length; i++) {
if (nums2[i] <= nums2[stack.peek()]) {
stack.push(i);
} else {
while (!stack.isEmpty() && nums2[stack.peek()] < nums2[i]) {
if (stack.peek() < nums.length) {
res[stack.peek()] = nums2[i];
} else {
res[stack.peek() - nums.length] = nums2[i];
}
stack.pop();
}
stack.push(i);
}
}
return res;
}
}
42. 接雨水
思路:本题十分经典。可以使用动态规划、双指针法、单调栈来解决,目前只介绍单调栈方法,二刷补充其他方法。
使用单调栈需要理解的几个问题:
- 单调栈是按照行的方向来存储雨水的
- 单调栈中元素的顺序应该是什么样的。
从栈底到栈头应该是从大到小的顺序。因为一旦发现更大的元素,说明我们就要接雨水(更新结果)了
- 遇到相同高度的柱子怎么办
遇到相同高度的柱子应当更新栈顶的元素,将其更新为最新的,用最右边的柱子来进行计算。
- 栈里应该保存什么值
这里栈中只需要保存数组的下标就好了。
class Solution {
public int trap(int[] height) { // 找每个柱子两边第一个大于该柱子高度的柱子
int res = 0;
Deque<Integer> stack = new LinkedList<>();
stack.push(0);
for (int i = 1; i < height.length; i++) {
if (height[i] < height[stack.peek()]) {
stack.push(i);
} else if (height[i] == height[stack.peek()]) {
stack.pop();
stack.push(i);
} else {
while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
int mid = stack.pop();
if (!stack.isEmpty()) {
int left = stack.peek();
int h = Math.min(height[left], height[i]) - height[mid];
int w = i - left - 1;
res += (h * w);
}
}
stack.push(i);
}
}
return res;
}
}