给定一个循环数组
nums
(nums[nums.length - 1]
的下一个元素是nums[0]
),返回nums
中每个元素的 下一个更大元素 。数字
x
的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出-1
。
输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
这道题和739. 每日温度类似,但是这道题可以循环去比较,所以涉及到2个nums数组,所以我们可以循环[0,2*nums.length)每次的索引下标可以是i%nums.length
就会两次遍历nums数组。
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] reslut=new int[nums.length];
Arrays.fill(reslut,-1);
Deque<Integer> stack=new LinkedList<>();
for(int i=0;i<2*nums.length;i++){
while(!stack.isEmpty()&&nums[i%nums.length]>nums[stack.peek()]){
reslut[stack.peek()]=nums[i%nums.length];
stack.pop();
}
stack.push(i%nums.length);
}
return reslut;
}
}
给定
n
个非负整数表示每个宽度为1
的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ahWRZiGA-1680681005247)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3781b66b-9b9e-4df2-9d89-5fe5efaf3e0c/Untitled.png)]
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
思路一:双指针(按照列来计算)
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 lHeight=height[i];
int rHeight=height[i];
for(int j=i+1;j<height.length;j++){
if(height[j]>rHeight){
rHeight=height[j];
}
}
for(int j=i-1;j>=0;j--){
if(height[j]>lHeight){
lHeight=height[j];
}
}
int h=Math.min(lHeight,rHeight)-height[i];
if(h>0){
sum+=h;
}
}
return sum;
}
}
以上代码的简洁版
class Solution {
public int trap(int[] height) {
int left = 0, right = height.length - 1;
int maxL = height[left], maxR = height[right];
int res = 0;
while (left < right) {
maxL = Math.max(maxL, height[left]);
maxR = Math.max(maxR, height[right]);
res += maxR > maxL ? maxL - height[left++] : maxR - height[right--];
}
return res;
}
}
思路二:单调栈(根据行来计算)
主要需要考虑三种情况:
情况一:当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[st.top()]
将下标index添加到stack中
情况二:当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[st.top()]
弹出stack栈顶元素,并将index添加到stack中
情况三:当前遍历的元素(柱子)高度大于栈顶元素的高度 height[i] > height[st.top()]
取stack弹出的元素为mid,stack剩余的栈顶元素为left,分别求高度和宽度
h = Math.min(height[left], height[index]) - height[mid];
w = index - left - 1;
所以最终雨水范围为h*w
class Solution {
public int trap(int[] height) {
int size = height.length;
if (size <= 2) return 0;
Stack<Integer> stack = new Stack<Integer>();
stack.push(0);
int sum = 0;
for (int index = 1; index < size; index++){
int stackTop = stack.peek();
if (height[index] < height[stackTop]){
stack.push(index);
}else if (height[index] == height[stackTop]){
stack.pop();
stack.push(index);
}else{
//pop up all lower value
int heightAtIdx = height[index];
while (!stack.isEmpty() && (heightAtIdx > height[stackTop])){
int mid = stack.pop();
if (!stack.isEmpty()){
int left = stack.peek();
int h = Math.min(height[left], height[index]) - height[mid];
int w = index - left - 1;
int hold = h * w;
if (hold > 0) sum += hold;
stackTop = stack.peek();
}
}
stack.push(index);
}
}
return sum;
}
}
最后做下来感觉还是双指针更简洁一些