Likou 503. The next bigger element II---first in and out monotonous stack

503. The Next Greater Element II

Given a looping array (the next element of the last element is the first element of the array), output the next larger element of each element. The next larger element of the number x is in the traversal order of the array. The first number after this number is larger than it, which means you should search for the next larger number in a loop. If it does not exist, -1 is output.

示例 1:

输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数; 
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
注意: 输入数组的长度不会超过 10000。

answer:

This question is similar to another question . The daily temperature-violence method is similar to the monotonous stack . If you are interested, you can take a look. And my enlightenment on the monotonous stack problem comes from a video inside. If you don't understand the stack problem very well, you can take a look at the video inside.

First of all, we need to analyze the meaning of the question. What we are looking for is the next larger element of each element in the loop array, and output -1 if there is none . The first difficulty of this problem lies in looping the array .
If it is not a circular array, then we can see that this is a "first -in-last-out " problem, and properly use the stack to solve it.
That is, we build an array simulation stack, and then traverse the nums array, if the stack is empty, directly push the corresponding nums[i] into the stack, otherwise, the following judgments will be made:
1. The element outside the stack is greater than the element on the top of the stack , and the problem is satisfied at this time It means "the next bigger element ", so we use the arr array to store the largest element corresponding to each element . In order to compare the elements below the top element of the stack with the elements outside the stack, we should pop the top element out of the stack , and the larger element you find can also become a larger element of other elements , so you need to use it again, that is The nums array performs an operation similar to " backtracking ".
2. The element outside the stack is not greater than the element on the top of the stack , that is, we did not find the so-called " next larger element ", so the elements outside the stack can be pushed into the stack.

After the above comparison, we can find the arr array that satisfies the meaning of the question, but note that this title is " loop array ".
So first we need to think about how to simulate the so-called "circular" state ?
What you need to know is that for linear traversal, the for loop structure is often used , and for circular traversal, the while loop structure is often used .

So here we use a while loop when traversing nums1.

And here is an important point , in order to form the so-called ring, we only need to search for nums1 twice .
why? You find that the so-called ring is just that every time a single element is searched, it is searched in the spatial range of the original array .
For example : 1, 2, 4, 5, 1, for 1, we need to search for 2, and then 4, 5, 1 in the process of searching if it is found to be greater than 1 and just exit . But the search space we allocated to him is the entire nums1 array ; for 2, the search is 4, 5, 1, 1, that is, if you add 2 itself, it is also searched in the entire nums1 array ; the same is true for 4, the search is 5, 1 , 1, 2 is also the entire nums1 array . So for each element, we search on the entire nums1 array space range , and we found that for the first element 1, it is enough to traverse nums1, and for 2, after traversing nums1, we need to traverse the first 1. For 4, we need to traverse the first 1 and the second 2 again, and for the last 1 we find that the traversal is equivalent to two nums1 , so the maximum is only equivalent to traversing nums1 twice, so we directly traverse nums1 twice It must be able to traverse completely , and for some elements, if you can find a " bigger element ", you will naturally find it after traversing nums1 once., And it’s useless if you can’t find it many times , so we can complete the operation of the circular array through this detail.

And what we need to store in the stack is not the element value, it should be the subscript of the element in the nums array , because we need to assign the arr array to the corresponding position later, and it is easier to find the element in nums by storing the subscript. Corresponding position, and then complete a mapping process .

Code:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* nextGreaterElements(int* nums, int numsSize, int* returnSize){
    
    
   int*arr=(int*)malloc(sizeof(int)*numsSize);//真正返回的数组
   int*temp=(int*)malloc(sizeof(int)*numsSize*2); //注意可能有不会出栈的情况,
   //而我们遍历2次nums1,因此需要两倍的大小
   memset(arr,-1,sizeof(int)*numsSize);//先变成-1
   int top = 0;//栈顶下标
   int i = 0;//此代表你遍历的元素个数
   while(i<2*numsSize-1)//最后一个不找是可以的
   //因为只有最后一个元素会受到“找完”的待遇,而自己本身又不会大于自己
   {
    
    
       int k = 0;
       k=i%numsSize;//取余操作是为了找到真正的环状数组元素对应的下标
       if(top==0)
       {
    
    
           temp[top]=k;
           top++;
           i++;
           continue;
       }
       else
       {
    
    
           if(nums[k]>nums[temp[top-1]])
           {
    
    
               arr[temp[top-1]]=nums[k];//存储进去
               top--;//不出栈比较不了后面的了
               i--;//回溯
           }
           else
           {
    
    
               temp[top]=k;
               top++;
           }
           i++;
           continue;
       }
   }
   *returnSize=numsSize;//表明返回的真正长度
    return arr;
}

Guess you like

Origin blog.csdn.net/xiangguang_fight/article/details/112789742