Article Directory
0. Topic
Given a circular array nums (the next element of nums[nums.length - 1] is nums[0]), return the next greater element of each element in nums.
The next greater element of the number x is the first greater number after this number, in array traversal order, which means you should loop to search for its next greater number. If not present, output -1.
Example 1:
输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
Example 2:
输入: nums = [1,2,3,4,3]
输出: [2,3,4,-1,4]
1. My solution: monotonic stack
1.1 Analysis
This question is the same as [LeetCode] 739, daily temperature. Difficulty Level: Moderate. A variety of solutions, worth studying Very similar, it is recommended to read 739 questions first
The two points that this question is more difficult than the 739 question are:
- The array needs to be looped from end to end, so find a way to implement array loop traversal.
- If there is no larger number for a certain number, -1 is returned; in fact, it is to find all the positions of the maximum value in the array (the maximum value is more than one)
Both of these difficulties have clever solutions:
- It is very troublesome to loop through the array directly. Another way of thinking is to copy the array and assemble a new array twice the length of the original. Isn't traversing the new array once equivalent to looping through the original array twice?
- Initialize the return value list with -1, the position with a larger value will be overwritten with the new value, the position with the maximum value will not be processed, and -1 will still be retained
In this way, both difficulties are solved, and we will consider what method to use next. The conclusion is:
For the problem of "finding the nearest one larger/smaller than the current value", you can use a monotonic stack to solve it
Why can a monotonic stack be used for this kind of problem? For a detailed explanation, please refer to Why use "monotonic stack"? From the perspective of "simple solution" to understand "monotonic stack"
1.2 Primary code, written directly according to the idea of monotonic stack
The code written directly according to the monotonic stack idea is as follows:
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
# 实现循环的一种方法:将数组复制一遍;取前 nums 个结果即可
new_nums=nums*2
length=len(new_nums)
ans=[-1]*length # 为了避免单独判断最大的元素的位置,用-1初始化数组
stack=[]
for i in range(length):
if not stack:
stack.append([i,new_nums[i]])
else:
if new_nums[i]>stack[-1][1]:
while stack and new_nums[i]>stack[-1][1]:
ans[stack[-1][0]]=new_nums[i]
stack.pop()
stack.append([i,new_nums[i]])
else:
stack.append([i,new_nums[i]])
return ans[:length//2]
1.3 Simplified code
Obviously, the code in 1.2 can be simplified, the simplified code is as follows:
class Solution:
def nextGreaterElements(self, nums: List[int]) -> List[int]:
# 实现循环的一种方法:将数组复制一遍;取前 nums 个结果即可
new_nums=nums*2
length=len(new_nums)
ans=[-1]*length # 为了避免单独判断最大的元素的位置,用-1初始化数组
stack=[]
for i in range(length):
if not stack:
stack.append([i,new_nums[i]])
else:
while stack and new_nums[i]>stack[-1][1]:
ans[stack[-1][0]]=new_nums[i]
stack.pop()
stack.append([i,new_nums[i]])
return ans[:length//2]