📜  在圆形数组中查找下一个更大的元素|套装2(1)

📅  最后修改于: 2023-12-03 15:07:59.877000             🧑  作者: Mango

在圆形数组中查找下一个更大的元素|套装2

什么是圆形数组?

圆形数组是一种特殊的数组,其最后一个元素与第一个元素相邻,即数组的起点和终点相连。举个例子,一个普通的数组 [1, 2, 3, 4, 5] 可以用一个圆形数组 [1, 2, 3, 4, 5, 1] 来表示。

问题描述

给定一个圆形数组 nums,对于其中的每一个元素 nums[i],需要找出它在圆形数组中下一个更大的元素。如果不存在更大的元素,则将其置为 -1。

例如,给定圆形数组 nums = [5, 4, 3, 2, 1],应该返回数组 [-1, 5, 5, 5, 5]

注意:圆形数组中的所有元素都是非负整数,且长度不超过 1000。

解决方案
方法一:暴力枚举

最简单的方法是枚举每一个元素,然后从当前位置向后依次查找下一个更大的元素。由于是圆形数组,我们需要用取模运算计算出下一个位置的索引。

时间复杂度为O(n^2),空间复杂度为O(1)。

class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        n = len(nums)
        ans = [-1] * n

        for i in range(n):
            for j in range(i + 1, n + i):
                if nums[j % n] > nums[i]:
                    ans[i] = nums[j % n]
                    break

        return ans
方法二:单调栈

我们可以使用单调栈来优化这个算法。首先将第一个元素入栈,然后遍历每一个元素。如果当前元素比栈顶元素大,说明当前元素就是栈顶元素的下一个更大的元素,将栈顶元素弹出,并将其下一个更大的元素存储在结果数组中。重复这个过程,直到当前元素比栈顶元素小为止。

当遍历完整个数组后,有可能栈中还剩余一些元素,这表示它们没有下一个更大的元素。我们只需要将它们的结果置为 -1 即可。

由于是圆形数组,我们需要把数组长度扩大一倍,在遍历之前把数组中的每一个元素拷贝一遍到末尾。这样,当我们到达数组的末尾时,就可以取模回到数组的起点了。

时间复杂度为O(n),空间复杂度为O(n)。

class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        n = len(nums)
        nums += nums
        ans = [-1] * n
        stack = []

        for i, num in enumerate(nums):
            while stack and nums[stack[-1]] < num:
                ans[stack.pop()] = num
            if i < n:
                stack.append(i)

        return ans
总结

圆形数组中查找下一个更大的元素的问题,可以用暴力枚举和单调栈两种方法来解决。单调栈的时间复杂度为O(n),比暴力枚举要快得多。这里需要注意,圆形数组需要扩大一倍,并在遍历之前把数组中的每一个元素拷贝一遍到末尾,这样才能让算法正确处理环形数组的情况。