文章目录
503.下一个更大元素II
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
示例 1:
输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;数字 2 找不到下一个更大的数;第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
思路:主要是首尾相接的问题,我的思路是执行两轮遍历。解题思路一致。
class Solution {
public int[] nextGreaterElements(int[] nums) {
int len = nums.length;
int[] res = new int[len];
Arrays.fill(res, -1);
Deque<Integer> stack = new LinkedList<>();
//stack.push(0)
for(int i = 0; i < 2 * len; i ++){
int index = i % len;
while(!stack.isEmpty() && nums[index] > nums[stack.peek()]){
res[stack.peek()] = nums[index];
stack.pop();
}
stack.push(index);
}
return res;
}
}
42. 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
方法一:双指针
class Solution {
public int trap(int[] height) {
//双指针解法
int len = height.length;
if(len <= 2)
return 0;
int res = 0;
for(int i = 1; i < len - 1; i ++){
int l = 0;
int r = 0;
for(int j = i - 1; j >= 0; j--){
l = Math.max(l, height[j]);
}
for(int j = i + 1; j < len; j++){
r = Math.max(r, height[j]);
}
res += Math.max(0, Math.min(l, r) - height[i]);
}
return res;
}
}
动态规划解法:
class Solution {
public int trap(int[] height) {
//双指针解法
int len = height.length;
if(len <= 2)
return 0;
int res = 0;
int[] maxLeft = new int[len];
int[] maxRight = new int[len];
maxLeft[0] = height[0];
for(int i = 1; i < len; i ++){
maxLeft[i] = Math.max(height[i], maxLeft[i - 1]);
}
maxRight[len - 1] = height[len - 1];
for(int i = len - 2; i >= 0; i --){
maxRight[i] = Math.max(height[i], maxRight[i + 1]);
}
for(int i = 1; i < len - 1; i ++){
res += Math.max(0, Math.min(maxLeft[i], maxRight[i]) - height[i]);
}
return res;
}
}
单调栈解法:
问题:思路有了但是好多地方没有考虑清楚,导致空指针异常。
class Solution {
public int trap(int[] height) {
int len = height.length;
if(len <= 2)
return 0;
int res = 0;
Deque<Integer> stack = new LinkedList<>();
stack.push(0);
for(int i = 1; i < len; i ++){
if(!stack.isEmpty()){
if(height[i] < height[stack.peek()]){
stack.push(i);
}else if(height[i] == height[stack.peek()]){
stack.pop();
stack.push(i);
}else{
//int topIndex = stack.pop();
while(!stack.isEmpty() && height[i] > height[stack.peek()]){
int topIndex = stack.pop();
if(!stack.isEmpty()){
int h = Math.min(height[stack.peek()], height[i]) - height[topIndex];
int w = i - stack.peek() - 1;
if(h * w > 0)
res += h * w;
}
//topIndex = stack.peek();
}
stack.push(i);
}
}
}
return res;
}
}