LeetCode 496. Next Greater Element I

65 阅读1分钟

LeetCode 496. Next Greater Element I

nums1 中数字 x 的 下一个更大元素 是指 x 在 nums2 中对应位置 右侧 的 第一个 比 x ****大的元素。

给你两个 没有重复元素 的数组 nums1 和 nums2 ,下标从 0 开始计数,其中nums1 是 nums2 的子集。

对于每个 0 <= i < nums1.length ,找出满足 nums1[i] == nums2[j] 的下标 j ,并且在 nums2 确定 nums2[j] 的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1 。

返回一个长度为 nums1.length 的数组 **ans **作为答案,满足 **ans[i] **是如上所述的 下一个更大元素 。

 

示例 1:

输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释: nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1

示例 2:

输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释: nums1 中每个值的下一个更大元素如下所述:
- 2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。
- 4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1

 

提示:

  • 1 <= nums1.length <= nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 104
  • nums1nums2中所有整数 互不相同
  • nums1 中的所有整数同样出现在 nums2 中

 

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

算法

(哈希表 + 单调栈) O(n)

首先将 nums2 里的所有元素存入 unordered_map 中,方便确定 nums1 中元素在 nums2 中的位置。
对 nums2 中的每个元素,需要求其右边第一个比其大的元素,这里可以用单调栈来实现。
建立一个单调递减的栈,如果新入栈的元素比栈顶元素值要大,则栈顶出栈,直到不比栈顶元素大为止。
栈顶出栈的过程中,就已经确定了其右边第一个比其大的元素就是最后要新入栈的元素。

时间复杂度

哈希表的时间复杂度为 O(n)

单调栈的时间复杂度为 O(n)

故总时间复杂度为 O(n)。

空间复杂度

需要额外 O(n) 的空间存储哈希表,单调栈等。

C++ 代码

class Solution {
public:
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums) {
int n = nums.size();
unordered_map\<int, int> hash;
for (int i = 0; i < n; i++)
hash\[nums\[i]] = i;

        stack<int> st;
        vector<int> greater(n);
        for (int i = 0; i < n; i++) {
            while (!st.empty() && nums[i] > nums[st.top()]) {
                greater[st.top()] = nums[i];
                st.pop();
            }
            st.push(i);
        }

        while (!st.empty()) {
            greater[st.top()] = -1;
            st.pop();
        }

        int m = findNums.size();
        vector<int> ans(m);
        for (int i = 0; i < m; i++)
            ans[i] = greater[hash[findNums[i]]];

        return ans;
    }

};