Likou 496. The next bigger element I---monotonic stack + hash mapping idea

496. The Next Greater Element I

Given two arrays nums1 and nums2 with no repeated elements, where nums1 is a subset of nums2. Find the next greater value in nums2 for each element in nums1.

The next greater element of the number x in nums1 refers to the first element greater than x to the right of the corresponding position in nums2. If it does not exist, the corresponding position outputs -1.

示例 1:

输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释:
    对于num1中的数字4,你无法在第二个数组中找到下一个更大的数字,因此输出 -1。
    对于num1中的数字1,第二个数组中数字1右边的下一个较大数字是 3。
    对于num1中的数字2,第二个数组中没有下一个更大的数字,因此输出 -1。
示例 2:

输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释:
    对于 num1 中的数字 2 ,第二个数组中的下一个较大数字是 3 。
    对于 num1 中的数字 4 ,第二个数组中没有下一个更大的数字,因此输出 -1 。
 
提示:
nums1和nums2中所有元素是唯一的。
nums1和nums2 的数组大小都不超过1000。

answer:

This question is similar to another question I wrote. The daily temperature-violence method is somewhat similar to the monotonous stack . If you are interested, you can take a look.

First of all, to understand the meaning of the question , we need to take the number in nums1 to the position of the equal number in nums2 to find a larger element . And the title shows that 1 is a subset of 2 , so if we directly hold the number in nums2 and find a larger element after the original position, it will be much more convenient, and finally go through a selection of the 1 array .

So how to complete the latter operation?

Through analysis, it can be seen that this is a similar "first in, last out " problem, so we can use the stack to solve it.
This question is a monotonous stacking process.
(Usually a one-dimensional array, to find the first element on the right (left) of any element that is larger (smaller) than itself will generally adopt the monotonic stack idea.)

That is, to build an array simulation stack to simulate our latter operation The "selection" process .

First, traverse the nums2 array. If the stack is empty, push it directly into the stack. When the stack is not empty, you need to divide into two situations:

1. At this time, the element outside the stack is larger than the element on the top of the stack , and it meets the meaning of "the next largest element", so the corresponding relationship between the two at this time is stored by creating a hash map , and then the element on the top of the stack is popped out of the stack to continue. The following comparison.

2. At this time, the element outside the stack is smaller than the element on the top of the stack , so it can be directly pushed into the stack, because it does not meet our requirements.

After selection, we can save the corresponding relationship between each element of the nums2 array and its " next largest element " by creating a hash map array . Then since what we really want is the case of a subset of nums1, nums2, according to the storage Make a selection on the hash map .

Code:

 * Note: The returned array must be malloced, assume caller calls free().
 */
int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    
    
    int *temp=(int*)malloc(sizeof(int)*nums2Size);//先定义大点为了防止越界,最后可以用return返回真正需要的长度
    int hashmap[nums2Size][2];//为nums1的尺寸会越界,因为会碰到不出栈的情况
    int k = 0;//哈希映射下标
    int top = 0;//栈顶元素下标
    for(int i=0;i<nums2Size;i++)//遍历nums2
    {
    
    
        if(top==0)//栈为空
        {
    
    
            temp[top]=nums2[i];
            top++;
        }
        else
        {
    
    
            if(nums2[i]>temp[top-1])//满足情况1
            {
    
    
                hashmap[k][0]=temp[top-1];
                hashmap[k][1]=nums2[i];
                k++;
                top--;//出栈操作
                i--;//因为栈外大的元素不是只用一次,他可以用好多次,我们只是让栈顶元素出栈即可,栈外需要再用
            }
            else
            {
    
    
                temp[top]=nums2[i];
                top++;
            }
        }
    }
    memset(temp,-1,sizeof(int)*nums1Size);//不能直接sizeof(temp),因为temp是动态数组
    									//先都填上-1更方便
    for(int i=0;i<nums1Size;i++)//遍历nums1
    {
    
    
        int j = 0;//设立个指针来查找我们的哈希映射
        while(j<=k)//由前面可知k是有效的哈希映射数组的长度
        {
    
    
            if(nums1[i]==hashmap[j][0])
            {
    
    
                temp[i]=hashmap[j][1];
                break;
            }
            else
            {
    
    
                j++;
            }
        }
    }
    *returnSize=nums1Size;//说明一下返回的长度
    return temp;
}

Guess you like

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