一、题目
Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn’t exist, output -1 for this number.
Example 1:
Input: [1,2,1]
Output: [2,-1,2]
Explanation: The first 1’s next greater number is 2;
The number 2 can’t find next greater number;
The second 1’s next greater number needs to search circularly, which is also 2.Note: The length of given array won’t exceed 10000.
二、思路
思路一:暴力法
连续这么多天跟着大佬后面看题解刷题,今天我也来尝试了一下自己写,没那么多厉害的方法,当然就用永远滴神——暴力法!😂
我的想法是遍历数组,使元素nums[i]
与循环数组后面的元素比较大小,
在本题中,循环数组只需循环一次就行,且对元素num[i]
,循环数组其实就是num[i+1], ...num[n-1], num[0], num[i]
,只需再遍历一遍这个循环数组,使其中的元素分别与num[i]
进行比较即可。
可行是可行,不过复杂度 O ( N 2 ) O(N^2) O(N2)这个耗时不是盖的……
思路二:单调栈
这个方法当然是参照题解的啦!重点在于积累嘛!再次推一下负雪明烛大佬的题解,有图解,这个好唉!😃
核心思想就是
遍历一遍列表,如果有递减的序列,先保存起来,因为它们的下一个更大元素相同
如果找到一个较大的元素,将该较大元素逐一与保存的元素进行比较,如果该元素更大,这个元素就是前面元素的下一个更大元素。
本题使用单调栈来实现:
如果栈为空,将当前元素放入
如果栈不为空,则比较当前元素与栈顶元素的大小
- 如果当前元素小于或等于栈顶元素,说明当前元素与栈顶元素的下一个更大相同,我们将当前元素入栈保存起来。
- 如果当前元素大于栈顶元素,这个元素就是我们前面说的较大值,逐个弹出栈中元素,直到当前元素小于或等于栈顶元素为止。
三、代码
思路一:
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
resultNum = []
for i in range(len(nums)):
mergeNums = nums[i+1:] + nums[:i+1]
for j in mergeNums:
if j > nums[i]:
resultNum.append(j)
break
else:
resultNum.append(-1)
return resultNum
思路二:
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
N = len(nums)
res = [-1] * N
stack = []
for i in range(N * 2):
while stack and nums[stack[-1]] < nums[i % N]:
res[stack.pop()] = nums[i % N]
stack.append(i % N)
return res