1. 程式人生 > 其它 >【LeetCode】C++ :簡單題 - 棧 496. 下一個更大元素 I

【LeetCode】C++ :簡單題 - 棧 496. 下一個更大元素 I

技術標籤:LeetCodeleetcode演算法

496. 下一個更大元素 I

難度簡單340

給定兩個沒有重複元素的陣列nums1nums2,其中nums1nums2的子集。找到nums1中每個元素在nums2中的下一個比其大的值。

nums1中數字x的下一個更大元素是指xnums2中對應位置的右邊的第一個比x大的元素。如果不存在,對應位置輸出 -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 。

提示:

  1. nums1nums2中所有元素是唯一的。
  2. nums1nums2的陣列大小都不超過1000。

說點題外話

這題的題意著實有點難理解,下面這句話的意思很容易理解錯,正確的理解是:下一個更大元素是指 x值 元素在nums2中的位置 的右邊第一個比 x 值大的元素

nums1中數字x的下一個更大元素是指x

nums2中對應位置的右邊的第一個比x大的元素。如果不存在,對應位置輸出 -1 。

1. 暴力法

該暴力法原先是在錯誤理解題意的基礎上寫的,後來發現不對,在正確理解意義後改了改之後能夠通過的,這裡是用時間換空間了。

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res;

        for(int i = 0; i < nums1.size(); i++){
            for(int j = 0; j < nums2.size(); j++){
                if (nums2[j] == nums1[i]){
                    for(int k = j; k < nums2.size(); k++){
                        if(nums2[k] > nums1[i]){
                            res.push_back(nums2[k]);
                            break;
                        }else if (k >= nums2.size() - 1 ){
                            res.push_back(-1);
                        }
                    }
                    break;
                }
            }
        } 
        return res;
    }
};

2. 單調棧

單調棧方法用空間換時間的思想

先不考慮nums1, 對nums2 中的每一個元素求出其下一個更大的元素,並將答案放到雜湊中,對nums中的數進行遍歷從雜湊表中找到答案。

難點是單調棧的實現

對元素nums2[i],判斷棧頂元素是否小於nums2[i],如果是,那麼這個棧頂元素的下一個更大元素為nums2[i],棧頂元素出棧(即第二個迴圈)

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        map<int, int> mp;
        stack<int> stack;

        for(int i : nums1){
            mp[i] = -1;
        }
        for (int i = 0; i < nums2.size(); i++){
            while(!stack.empty() &&stack.top() < nums2[i]){
                mp[stack.top()] = nums2[i];
                stack.pop();
            }
            stack.push(nums2[i]);
        }

        for(int i = 0; i< nums1.size(); i++){
            nums1[i] = mp[nums1[i]];
        }
        return nums1;
    }
};