Medium
题目描述
给定一个循环整数数组 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 <= nums.length <= 10^4-10^9 <= nums[i] <= 10^9
解题思路
这道题是经典的单调栈问题的循环数组变种。
核心思路:
- 单调栈基础:使用单调递减栈来找下一个更大元素。栈中存储数组下标,栈底到栈顶对应的元素值递减。
- 处理循环:由于数组是循环的,我们需要遍历两遍数组。可以通过取模运算
i % n来实现循环访问。
算法步骤:
- 初始化结果数组为
-1 - 使用栈存储下标,遍历
2*n次(两遍数组) - 对于每个位置,弹出栈中所有小于当前元素的下标,并更新它们的结果
- 只在第一遍遍历时将当前下标入栈(避免重复处理)
时间复杂度优化: 相比暴力解法的 O(n²),单调栈解法只需 O(n) 时间,因为每个元素最多入栈和出栈各一次。
推荐解法: 单调栈解法,时间和空间效率都很好。
代码实现
class Solution {
public:
vector<int> nextGreaterElements(vector<int>& nums) {
int n = nums.size();
vector<int> result(n, -1);
stack<int> st;
for (int i = 0; i < 2 * n; i++) {
while (!st.empty() && nums[st.top()] < nums[i % n]) {
result[st.top()] = nums[i % n];
st.pop();
}
if (i < n) {
st.push(i);
}
}
return result;
}
};
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
n = len(nums)
result = [-1] * n
stack = []
for i in range(2 * n):
while stack and nums[stack[-1]] < nums[i % n]:
result[stack.pop()] = nums[i % n]
if i < n:
stack.append(i)
return result
public class Solution {
public int[] NextGreaterElements(int[] nums) {
int n = nums.Length;
int[] result = new int[n];
Array.Fill(result, -1);
Stack<int> stack = new Stack<int>();
for (int i = 0; i < 2 * n; i++) {
while (stack.Count > 0 && nums[stack.Peek()] < nums[i % n]) {
result[stack.Pop()] = nums[i % n];
}
if (i < n) {
stack.Push(i);
}
}
return result;
}
}
var nextGreaterElements = function(nums) {
const n = nums.length;
const result = new Array(n).fill(-1);
const stack = [];
for (let i = 0; i < 2 * n; i++) {
while (stack.length > 0 && nums[stack[stack.length - 1]] < nums[i % n]) {
result[stack.pop()] = nums[i % n];
}
if (i < n) {
stack.push(i);
}
}
return result;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 每个元素最多入栈和出栈各一次 |
| 空间复杂度 | O(n) | 栈最多存储 n 个元素 |