leetcode-496-Next Greater Element I

Posted chenjx85

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode-496-Next Greater Element I相关的知识,希望对你有一定的参考价值。

题目描述:

You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1‘s elements in the corresponding places of nums2.

The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number.

 

Example 1:

Input: nums1 = [4,1,2], nums2 = [1,3,4,2].
Output: [-1,3,-1]
Explanation:
    For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.
    For number 1 in the first array, the next greater number for it in the second array is 3.
    For number 2 in the first array, there is no next greater number for it in the second array, so output -1.

 

Example 2:

Input: nums1 = [2,4], nums2 = [1,2,3,4].
Output: [3,-1]
Explanation:
    For number 2 in the first array, the next greater number for it in the second array is 3.
    For number 4 in the first array, there is no next greater number for it in the second array, so output -1.

 

Note:

  1. All elements in nums1 and nums2 are unique.
  2. The length of both nums1 and nums2 would not exceed 1000.

 

要完成的函数:

vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) 

 

说明:

1、给定两个vector,比如[3,2]和[2,4,3,1],第一个vector是第二个的子集。要求输出第二个vector中比第一个vector中某个元素大,并且位置上也在其右边的数。要是没找到的话,输出-1。

比如我们给出的例子中,3的next greater element没有,所以我们输出-1。2的next greater element是4,所以输出4。

2、理解题意之后,一般想法是双重循环。

我们可以设定第一个vector为vector1,第二个为vector2。

对于每个vector1中的元素,遍历vector2,找到其位置,在其位置右边继续找,直到找到比它大的数值。

双重循环,这道题可解。

代码如下:

    vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) 
    {
        vector<int>::iterator iter;
        vector<int>res;
        for(int i=0;i<findNums.size();i++)
        {
            iter=find(nums.begin(),nums.end(),findNums[i]);//找到位置
            iter++; 
            while(iter!=nums.end())//循环处理,直到找到比它大的数
            { 
                if(*iter>findNums[i])
                {
                    res.push_back(*iter);
                    break;
                }
                else
                    iter++; 
            }
            if(iter==nums.end())//边界情况处理
                res.push_back(-1);
        }    
        return res; 
    } 

上述代码实测13ms,beats 45.84% of cpp submissions。

 

3、改进:

双重循环实在太浪费信息了。比如[8,7,1,2,3,4,5,6,9,10],我们要找8的next greater element,要比较中间的1/2/3/4/5/6,才能到9;要找7的next greater element,也要比较中间的1/2/3/4/5/6。我们之前比较过一次,但这些信息完全没有被利用到,又重复比较了一次。

我们可以从左边找起,把那些找到了对应值(也就是next greater element)的删去,然后停留在原本vector2中的,可以想到,是一个下降的vector。

在评论区中参考了大神的代码,自己修改了一下,增加了注释,分享给大家。

代码如下:

    vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) 
    {
        stack<int> s1;//存储还没有找到对应值的数
        unordered_map<int, int> m1;//建立对应表
        for (int i=0;i<nums.size();i++) //对每个新的数进行处理
        {
            while (s1.size() && s1.top() < nums[i]) 
            {
                m1[s1.top()] = nums[i];
                s1.pop();
            }
            s1.push(nums[i]);
        }
        vector<int> res;
        for (int i=0;i<findNums.size();i++) 
            res.push_back(m1.count(findNums[i]) ? m1[findNums[i]] : -1);
        return res;
    }

这份代码其实建立了所有能找到next greater element的元素的对应表。

我们当然也可以不用栈来存储,理解起来会更加直接。只不过使用栈使得代码更好写。

上述代码实测11ms,beats 84.93% of cpp submissions。

的确是很优秀的做法。

以上是关于leetcode-496-Next Greater Element I的主要内容,如果未能解决你的问题,请参考以下文章

leetcode-496-Next Greater Element I

[leetcode]496. Next Greater Element I下一个较大元素

Leetcode 496. Next Greater Element I

leetcode496. Next Greater Element I

greater

496. Next Greater Element I