❓503. 下一个更大元素 II
难度:中等
给定一个循环数组 nums
( nums[nums.length - 1]
的下一个元素是 nums[0]
),返回 nums
中每个元素的 下一个更大元素 。
数字 x
的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1
。
示例 1:
输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
示例 2:
输入: nums = [1,2,3,4,3]
输出: [2,3,4,-1,4]
提示:
- 1 < = n u m s . l e n g t h < = 1 0 4 1 <= nums.length <= 10^4 1<=nums.length<=104
- − 1 0 9 < = n u m s [ i ] < = 1 0 9 -10^9 <= nums[i] <= 10^9 −109<=nums[i]<=109
💡思路:单调栈
和739. 每日温度解法类似,使用单调栈解决;
-
单调栈中保存的是下标索引,从栈底到栈顶的下标在数组
nums
中对应的值是单调不升的。 -
但不同的是该题目是循环数组,对每一个元素最多遍历一圈,即回到自己的位置。
-
从而可以想到我们可以把这个循环数组 “拉直”, 即复制原数组所有元素拼接在原序列的后面。
-
这样我们就可以将这个新序列当作普通序列,用上题的方法来处理。
🍁代码:(Java、C++)
Java
class Solution {
public int[] nextGreaterElements(int[] nums) {
int n = nums.length;
int[] ans = new int[n];
Arrays.fill(ans, -1);
Stack<Integer> indexs = new Stack<>();
for(int i = 0; i < 2 * n; i++){
while(!indexs.isEmpty() && nums[i % n] > nums[indexs.peek()]){
ans[indexs.pop()] = nums[i % n];
}
if(i < n){
indexs.push(i);
}
}
return ans;
}
}
C++
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n = nums.size();
vector<int> ans(n, -1);
stack<int> indexs;
for(int i = 0; i < 2 * n; i++){
while(!indexs.empty() && nums[i % n] > nums[indexs.top()]){
ans[indexs.top()] = nums[i % n];
indexs.pop();
}
if(i < n){
indexs.push(i);
}
}
return ans;
}
};
🚀 运行结果:
🕔 复杂度分析:
- 时间复杂度:
O
(
n
)
O(n)
O(n),其中
n
是序列的长度。我们需要遍历该数组中每个元素最多 2 次。 - 空间复杂度:
O
(
n
)
O(n)
O(n),其中
n
是序列的长度。空间复杂度主要取决于栈的大小,栈的大小至多为n
。
题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我 leetCode专栏,每日更新!