一、下一个更大元素 I
给两个没有重复元素的数组nums1
和nums2
,其中nums1
是nums2
的子集。请找出nums1
中每个元素在nums2
中的下一个比其大的值。nums1
中数字 x
的下一个更大元素是指 x
在 nums2
中对应位置的右边的第一个比 x
大的元素。如果不存在,对应位置输出 -1 。
- 忽略数组
nums1
,对nums2
中的每一个元素,求出其下一个更大的元素。随后将其放入HashMap,再遍历数组nums1
,并直接找出答案。对于nums2
,使用单调栈来找到每个元素的下一个更大元素。
public class Solution{
public int[] nextGreaterElement(int[] findNums, int[] nums){
Stack<Integer> stack = new Stack<>();
HashMap<Integer, Integer> map = new HashMap<>();
int[] res = new int[findNums.length];
for(int i = 0; i < nums.length; i++){
while(!stack.empty() && nums[i] > stack.peek()){
map.put(stack.pop(), nums[i]);
}
stack.push(nums[i]);
}
while(!stack.empty()){
map.put(stack.pop(), -1);
}
for(int i = 0; i < findNums.length; i++){
res[i] = map.get(findNums[i]);
}
return res;
}
}
二、下一个更大元素Ⅱ
给定一个循环数组(最后一个元素的下一个元素是数组的),输出每个元素的下一个更大元素。数字x的下一个更大元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味值应该循环搜索他的下一个更大的数。如果不存在,则输出-1。
输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
单调栈+循环数组
建立【单调递减栈】,对原数组遍历:
- 如果栈为空,则把当前元素放入栈内;
- 如果栈不为空,则需要判断当前元素和栈顶元素的大小;
– 如果当前元素比栈顶元素大;说明当前元素是前面一些元素的[下一个更大元素],逐个弹出栈顶元素,直到当前元素比栈顶元素小为止。
– 如果当前元素比栈顶元素小;说明当前元素的[下一个更大元素]与栈顶元素相同,则把当前元素入栈。
class Solution{
public int[] newxtGreaterElements(int[] nums){
int n = nums.length;
int res = new int[n];
Arrays.fill(res, -1);
// 栈内存放的是元素的下标,不是具体的值
Stack<Integer> stack = new Stack<>();
// 把数组遍历两边
for (int i = 0; i < 2 * n; i++) {
int index = i % n;
// 如果栈顶元素对应的值比nums[index]小,说明栈顶元素遇见了[下一个更大元素]
// 此时栈顶元素出栈,让其对应的位置变为nums[index ]
while (!stack.isEmpty() && nums[index] > nums[stack.peek()]) {
// 弹出栈顶元素(下标)
res[stack.pop()] = nums[index ];
}
stack.push(index); // 入栈的是nums数组的下标
}
return res;
}
}