1. 程式人生 > >leetcode-496-Next Greater Element I

leetcode-496-Next Greater Element I

rip 原本 理解 這份 where exp plan array iss

題目描述:

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