题目描述:
给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。
示例 1:
输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
注意: 输入数组的长度不会超过 10000。
思路:首先这道题按照普通的遍历进行肯定是没有问题的
代码如下:
class Solution {
public int[] nextGreaterElements(int[] nums) {
if(nums == null ||nums.length == 0){
return new int[]{};
}
int max = nums[0];
for (int i : nums) {
if(max < i){
max = i;
}
}
int result[] = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
int index = i + 1;
if(nums[i] == max){
result[i] = -1;
}else {
while (true) {
if(nums[index % nums.length] > nums[i]){
result[i] = nums[index % nums.length];
break;
}
index ++;
}
}
}
return result;
}
}
但是复杂度很高,不推荐,因此考虑借鉴之前的那道题目
因为这个可以循环,考虑可以将其变成二倍
注意和之前的那个题目区别是这里有重复,因此map的key就是索引,value就是下标对应的值,stack存放的也是索引,需要注意一下
class Solution {
public int[] nextGreaterElements(int[] nums) {
if(nums == null || nums.length == 0){
return new int[]{};
}
int result[] = new int[nums.length];
int tem[] = new int[nums.length * 2];
int max = nums[0];
for (int i = 0; i < tem.length; i++) {
tem[i] = nums[i % nums.length];
max = tem[i] > max ? tem[i]:max;
}
System.out.println(Arrays.toString(tem));
//stack存放的也是下标,map里面存放的key是下标,value是对应的值
Stack<Integer> stack = new Stack<>();
int len = tem.length;
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < tem.length; i++) {
while (!stack.isEmpty() && tem[stack.peek()] < tem[i]) {
map.put(stack.pop(), tem[i]);
}
stack.push(i % len);
}
System.out.println(map.toString());
int i = 0;
for (int j = 0; j < result.length; j++) {
result[j] = map.getOrDefault(j, -1);
}
return result;}
}