题目
概述:给定一个循环数组,输出每个元素的下一个更大元素,如果不存在则输出-1
输入:循环数组,数组长度范围[0, 10000],数组最后一个元素的下一个元素是数组第一个元素
输出:每个元素的下一个更大元素,没有则输出-1
出处:https://leetcode-cn.com/problems/next-greater-element-ii/
思路
-
数组最后一个元素的下一个更大的元素是数组从头开始遍历的第一个比最后一个元素大的元素
要遍历完数组直至无法得到下一个更大的元素
空数组要单独校验不要忘
用next数组记录每个元素的下一个更大元素的数组索引
-
对于数组中的任意一个元素,假设它后面的所有元素已求出下一个更大元素,则:
- 若该元素小于下一个元素,则它的下一个更大元素即为下一个元素
- 若该元素大于等于下一个元素,记当前索引为i:
- next[i + 1] == -1 => 没有比该元素更大的元素
- 该元素 < next[i + 1]索引处的元素 => 该元素的下一个更大元素为next[i + 1]索引处的元素
- 该元素 >= next[i + 1]索引处的元素 => 继续和next[next[i + 1]]索引处的元素比较
由于最后一个元素的下一个更大元素可以求得,根据上述规则,从后向前推可以推得所有元素的下一个更大的元素
代码
class Solution {
public int[] nextGreaterElements(int[] nums) {
int length = nums.length;
int j = length - 1;
int[] result = new int[length];
int[] next = new int[length];
if (length == 0) { //avoid j OutOfArrayBounds
return result;
}
for (int i = 0; i < length - 1; ++i) {
if (nums[i] > nums[j]) {
result[j] = nums[i];
next[j] = i;
j = i;
}
}
result[j] = -1;
next[j] = -1;
int k;
for (int i = length - 2; i >= 0; --i) {
if (nums[i] < nums[i + 1]) {
result[i] = nums[i + 1];
next[i] = i + 1;
} else {
k = i + 1;
while (true) {
if (next[k] == -1) {
result[i] = -1;
next[i] = -1;
break;
} else if (nums[i] < nums[next[k]]) {
result[i] = nums[next[k]];
next[i] = next[k];
break;
} else {
k = next[k];
}
}
}
}
return result;
}
}