一句话总结:接雨水单调栈不如双指针。
原题链接:503 下一个更大元素II
和昨天的每日温度类似,只需要将遍历范围从n -> n * 2,然后指针取模即可;代码如下:
class Solution {
public int[] nextGreaterElements(int[] nums) {
if (nums.length == 1) return new int[]{-1};
int n = nums.length;
int[] ans = new int[n];
Arrays.fill(ans, -1);
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < 2 * n; ++i) {
while (!stack.isEmpty() && nums[i % n] > nums[stack.peek()]) {
ans[stack.peek()] = nums[i % n];
stack.pop();
}
stack.push(i % n);
}
return ans;
}
}
还有可降低时间复杂度的数组替代栈的解法:
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] ans = new int[nums.length];
int[] stack = new int[nums.length];
int top = -1;
for(int i = 0; i < nums.length; i++) {
while(top != -1 && nums[i] > nums[stack[top]]) {
ans[stack[top--]] = nums[i];
}
stack[++top] = i;
}
for(int i = 0; i < nums.length; i++) {
while(top != -1 && nums[i] > nums[stack[top]]) {
ans[stack[top--]] = nums[i];
}
}
while(top != -1){
ans[stack[top--]] = -1;
}
return ans;
}
}
原题链接: 42 接雨水
经典接雨水。
class Solution {
public int trap(int[] height) {
if (height == null || height.length == 0) {
return 0;
}
int res = 0;
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < height.length; i++) {
while (!stack.isEmpty() && height[i] >= height[stack.peek()]) {
int top = stack.pop();
if (stack.isEmpty()) {
break;
}
int left = stack.peek();
int w = i - left - 1;
int h = Math.min(height[left], height[i]) - height[top];
res += w * h;
}
stack.push(i);
}
return res;
}
}
更优解法是双指针解法:
class Solution {
public int trap(int[] height) {
int ans = 0, left = 0, right = height.length - 1, preMax = 0, sufMax = 0;
while (left < right) {
preMax = Math.max(preMax, height[left]);
sufMax = Math.max(sufMax, height[right]);
ans += preMax < sufMax ? preMax - height[left++] : sufMax - height[right--];
}
return ans;
}
}