【LeetCode】503, Next Bigger Element II. Difficulty Level: Moderate. In-depth understanding of the "next bigger/smaller problem" commonly used monotonic stack method

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:

  1. The array needs to be looped from end to end, so find a way to implement array loop traversal.
  2. 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:

  1. 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?
  2. 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]

Guess you like

Origin blog.csdn.net/qq_43799400/article/details/131730916