[leetcode每日一题2021/10/26]496. 下一个更大元素 I【简单】进阶:单调栈+哈希表

496. 下一个更大元素 I

  • 题目
  • 思路
    • 单调栈+哈希表
  • 代码
  • 算法复杂度

题目来源于leetcode,解法和思路仅代表个人观点。传送门。
难度:简单
时间:10min

题目

给你两个 没有重复元素 的数组 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 <= nums1.length <= nums2.length <= 1000
0 <= nums1[i], nums2[i] <=10^4
nums1nums2中所有整数
互不相同 nums1 中的所有整数同样出现在 nums2

进阶: 你可以设计一个时间复杂度为 O(nums1.length + nums2.length)的解决方案吗?

思路

  1. 暴力解。这就不写了。
  2. 单调栈+哈希表。

单调栈+哈希表

其实这是一类题——单调栈。所以记录一下。

识别关键字:
下一个,更大、更小


因为,
nums1nums2的子集。
nums1nums都是无序的。
结果求的是nums1中所有元素的下一个更大的元素

那么,
我们需要使用一个map记录nums1元素的下一个更大的元素
而且,使用单调栈,我们可以求出nums2中所有元素的下一个更大元素


单调栈运行过程(求下一个更大的数):
对于nums2的所有元素:

  1. 如果栈为空,入栈当前元素
  2. 如果栈不为空,栈顶元素当前元素比较。
  • 如果栈顶元素 >= 当前元素
    入栈当前元素
  • 如果栈顶元素 < 当前元素
    当前元素就是,栈顶元素下一个更大的元素
    执行循环,出栈所有比当前元素小的元素(其下一个更大的元素都是当前元素)。

代码

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        int left = 0;
        int rihgt = 0;
        int n1 = nums1.size();
        int n2 = nums2.size();
        vector<int> ans(n1,-1);

        unordered_map<int,int> mmap;
        stack<int> s;
        for(int i=0;i<n2;i++){
            if(s.empty()){
                s.push(nums2[i]);
            }else if(s.top() < nums2[i]){
                while(!s.empty() && s.top() < nums2[i]){
                    int num = s.top();
                    s.pop();
                    mmap[num] = nums2[i];
                }
                s.push(nums2[i]);
            }else if(s.top() >= nums2[i]){
                s.push(nums2[i]);
            }
        }
        for(int i=0;i<n1;i++){
            if(mmap.count(nums1[i]) == 0){
                continue;
            }
            ans[i] = mmap[nums1[i]];
        }
        return ans;
    }
};

优化结构代码

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        int left = 0;
        int rihgt = 0;
        int n1 = nums1.size();
        int n2 = nums2.size();
        vector<int> ans(n1,-1);

        unordered_map<int,int> mmap;
        stack<int> s;
        for(int i=0;i<n2;i++){
            while(!s.empty() && s.top() < nums2[i]){
                int num = s.top();
                s.pop();
                mmap[num] = nums2[i];
            }
            s.push(nums2[i]);
        }
        for(int i=0;i<n1;i++){
            if(mmap.count(nums1[i]) == 0){
                continue;
            }
            ans[i] = mmap[nums1[i]];
        }
        return ans;
    }
};

算法复杂度

时间复杂度: O ( n 1 + n 2 ) O(n_1+n_2) O(n1+n2),其中 n 1 n_1 n1nums1的长度, n 2 n_2 n2nums2的长度。 O ( n 1 ) O(n_1) O(n1)用于遍历生成答案, O ( n 2 ) O(n_2) O(n2)用于求下一个最大的元素
空间复杂度: O ( n 1 + n 2 ) O(n_1+n_2) O(n1+n2),其中 n 1 n_1 n1nums1的长度, n 2 n_2 n2nums2的长度。 O ( n 1 ) O(n_1) O(n1)用于哈希表, O ( n 2 ) O(n_2) O(n2)用于单调栈。

你可能感兴趣的:(算法,leetcode,算法)