给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。
数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。
示例 1:
输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/next-greater-element-ii
本题是将数组变为循环数组:因此单调栈的查找需要 2*N的长度;
创建一个新的数组,然后进行单调栈的判断,同时需要判断下标是否越界
1)单调栈思想
- class Solution {
- public int[] nextGreaterElements(int[] nums) {
- //两个数组拼成一个,时间复杂度为 o(2N)
- int l = nums.length;
- int[] nums1 = new int[2 * l];
- //将新的数组赋值
- for(int i = 0;i < 2 * l;i++){
- nums1[i] = nums[i % l];
- }
-
- int[] res = new int[l];
- Arrays.fill(res,-1);
- Stack
stack = new Stack<>(); - for(int i = 0;i < 2 * l;i++){
- while(!stack.isEmpty() && nums1[i] > nums1[stack.peek()]){
- int index = stack.pop();
- if(index < l){
- res[index] = nums1[i];
- }
- }
- stack.push(i);//这次往里面放下标
- }
- return res;
- }
- }
同样可以不构件新的数组,直接在原有的数组基础上,每次都取余即可:
- class Solution {
- public int[] nextGreaterElements(int[] nums) {
- //两个数组拼成一个,时间复杂度为 o(2N)
- int l = nums.length;
- int[] res = new int[l];
- Arrays.fill(res,-1);
- Stack
stack = new Stack<>(); - for(int i = 0;i < 2 * l;i++){
- while(!stack.isEmpty() && nums[i % l] > nums[stack.peek() % l]){
- int index = stack.pop();
- if(index < l){
- res[index] = nums[i % l];
- }
- }
- stack.push(i);//这次往里面放下标
- }
- return res;
- }
- }
可以继续简化,判断条件
- class Solution {
- public int[] nextGreaterElements(int[] nums) {
- //两个数组拼成一个,时间复杂度为 o(2N)
- int l = nums.length;
- int[] res = new int[l];
- Arrays.fill(res,-1);
- Stack
stack = new Stack<>(); - for(int i = 0;i < 2 * l;i++){
- while(!stack.isEmpty() && nums[i % l] > nums[stack.peek()]){
- res[stack.pop()] = nums[i % l];
- }
- if(i < l)
- stack.push(i);//这次往里面放下标
- }
- return res;
- }
- }