LeetCode 503.下一个更大元素II
LeetCode 42. 接雨水
给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。
数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。
class Solution {
public int[] nextGreaterElements(int[] nums) {
Deque<Integer> stack = new LinkedList<>();
int[] res = new int[nums.length];
Arrays.fill(res, -1);
stack.push(0);
int length = nums.length;
for (int i = 0; i < length * 2; i++) {
while (!stack.isEmpty() && nums[i % length] > nums[stack.peek()]) {
res[stack.peek()] = nums[i % length];
stack.pop();
}
stack.push(i % length);
}
return res;
}
}
min(lHeight, rHeight) - height。
超时
class Solution {
public int trap(int[] height) {
// 暴力
int sum = 0;
for (int i = 0; i < height.length; i++) {
// 第一个柱子和最后一个柱子不接水
if(i == 0 || i == height.length - 1) continue;
int rHeight = height[i]; // 记录右边柱子的最高高度
int lHeight = height[i]; // 记录左边柱子的最高高度
for (int r = i + 1; r < height.length; r++){
rHeight = Math.max(rHeight, height[r]);
}
for (int l = i - 1; l >= 0; l--){
lHeight = Math.max(lHeight, height[l]);
}
int h = Math.min(rHeight, lHeight) - height[i];
if (h > 0) sum += h;
}
return sum;
}
}
双指针优化
maxLeft[i] = max(height[i], maxLeft[i - 1]);
maxRight[i] = max(height[i], maxRight[i + 1]);
class Solution {
public int trap(int[] height) {
// 双指针优化
if (height.length <= 2) return 0;
int[] maxLeft = new int[height.length];
int[] maxRight = new int[height.length];
int length = height.length;
// 记录每个柱子左边柱子的最大高度
maxLeft[0] = height[0];
for (int i = 1; i < length; i++) {
maxLeft[i] = Math.max(height[i], maxLeft[i-1]);
}
// 记录每个柱子右边柱子的最大高度
maxRight[length-1] = height[length-1];
for (int i = length-2; i >= 0; i--) {
maxRight[i] = Math.max(height[i], maxRight[i+1]);
}
// 求和
int sum = 0;
for (int i = 0; i < length; i++) {
int count = Math.min(maxLeft[i], maxRight[i]) - height[i];
if (count > 0) sum += count;
}
return sum;
}
}
class Solution {
public int trap(int[] height) {
if (height.length <= 2) return 0;
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
int sum = 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 {
// pop up all lower value
while (!stack.isEmpty() && height[i] > height[stack.peek()]) {
int mid = stack.peek();
stack.pop();
if (!stack.isEmpty()) {
int h = Math.min(height[stack.peek()], height[i]) - height[mid];
int w = i - stack.peek() - 1;
int hold = h * w;
if (hold > 0) sum += hold;
}
}
stack.push(i);
}
}
return sum;
}
}