1.题目描述
给定一个循环数组
nums
(nums[nums.length - 1]
的下一个元素是nums[0]
),返回nums
中每个元素的 下一个更大元素 。数字
x
的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出-1
。
输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
输入: nums = [1,2,3,4,3]
输出: [2,3,4,-1,4]
提示:
1 <= nums.length <= 104
-109 <= nums[i] <= 109
2.思路分析
2.1 单调栈+循环数组
2.2.1 什么时候使用单调栈?
一般是一维数组,要寻找任一一个元素的右边或者左边第一个比自己大的或者小的元素的位置
2.2.2 单调栈的本质是什么?
以空间换时间
2.2.3 单调栈里存储的是什么?
存储元素的下标即可,如果需要获取对应的元素, 直接T[i]即可获取
2.2.34 单调栈里的元素是递增还是递减?
方向:栈顶->栈底
具体递增还是递减根据具体题目而定,本题还是递增(栈顶->栈底:小->大),这样才能找到右边第一个比自己大的元素。
Q:如何循环数组?
举个栗子:对于数组[2,3,1],遍历一次是不够的, 最后单调栈中将剩余 [3,1],其中元素[1] 的下一个更大元素还是不知道的。
即复制该序列的前 n−1 个元素拼接在原序列的后面
3.代码实现
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
# 单调
n = len(nums)
result = [-1] * n
stack = []
for i in range(2 * n - 1):
while stack and nums[i % n] > nums[stack[-1]]:
result[stack[-1]] = nums[i % n]
stack.pop()
stack.append(i % n)
return result
复杂度分析
- 时间复杂度: O(n),其中 n 是序列的长度。我们需要遍历该数组中每个元素最多 2 次,每个元素出栈与入栈的总次数也不超过 4 次。
- 空间复杂度: O(n),其中 n 是序列的长度。空间复杂度主要取决于栈的大小,栈的大小至多为 2n-1。