--- comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/solution/0400-0499/0496.Next%20Greater%20Element%20I/README.md tags: - 栈 - 数组 - 哈希表 - 单调栈 --- # [496. 下一个更大元素 I](https://leetcode.cn/problems/next-greater-element-i) [English Version](/solution/0400-0499/0496.Next%20Greater%20Element%20I/README_EN.md) ## 题目描述

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 。

 

提示:

 

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

## 解法 ### 方法一:单调栈 单调栈常见模型:找出每个数左/右边**离它最近的**且**比它大/小的数**。模板: ```python stk = [] for i in range(n): while stk and check(stk[-1], i): stk.pop() stk.append(i) ``` 对于本题,先对将 `nums2` 中的每一个元素,求出其下一个更大的元素。随后对于将这些答案放入哈希表 $m$ 中,再遍历数组 `nums1`,并直接找出答案。对于 `nums2`,可以使用单调栈来解决这个问题。 时间复杂度 $O(M+N)$,其中 $M$ 和 $N$ 分别为数组 `nums1` 和 `nums2` 的长度。 #### Python3 ```python class Solution: def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: m = {} stk = [] for v in nums2: while stk and stk[-1] < v: m[stk.pop()] = v stk.append(v) return [m.get(v, -1) for v in nums1] ``` #### Java ```java class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Deque stk = new ArrayDeque<>(); Map m = new HashMap<>(); for (int v : nums2) { while (!stk.isEmpty() && stk.peek() < v) { m.put(stk.pop(), v); } stk.push(v); } int n = nums1.length; int[] ans = new int[n]; for (int i = 0; i < n; ++i) { ans[i] = m.getOrDefault(nums1[i], -1); } return ans; } } ``` #### C++ ```cpp class Solution { public: vector nextGreaterElement(vector& nums1, vector& nums2) { stack stk; unordered_map m; for (int& v : nums2) { while (!stk.empty() && stk.top() < v) { m[stk.top()] = v; stk.pop(); } stk.push(v); } vector ans; for (int& v : nums1) ans.push_back(m.count(v) ? m[v] : -1); return ans; } }; ``` #### Go ```go func nextGreaterElement(nums1 []int, nums2 []int) []int { stk := []int{} m := map[int]int{} for _, v := range nums2 { for len(stk) > 0 && stk[len(stk)-1] < v { m[stk[len(stk)-1]] = v stk = stk[:len(stk)-1] } stk = append(stk, v) } var ans []int for _, v := range nums1 { val, ok := m[v] if !ok { val = -1 } ans = append(ans, val) } return ans } ``` #### TypeScript ```ts function nextGreaterElement(nums1: number[], nums2: number[]): number[] { const map = new Map(); const stack: number[] = [Infinity]; for (const num of nums2) { while (num > stack[stack.length - 1]) { map.set(stack.pop(), num); } stack.push(num); } return nums1.map(num => map.get(num) || -1); } ``` #### Rust ```rust use std::collections::HashMap; impl Solution { pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { let mut map = HashMap::new(); let mut stack = Vec::new(); for num in nums2 { while num > *stack.last().unwrap_or(&i32::MAX) { map.insert(stack.pop().unwrap(), num); } stack.push(num); } nums1 .iter() .map(|n| *map.get(n).unwrap_or(&-1)) .collect::>() } } ``` #### JavaScript ```js /** * @param {number[]} nums1 * @param {number[]} nums2 * @return {number[]} */ var nextGreaterElement = function (nums1, nums2) { let stk = []; let m = {}; for (let v of nums2) { while (stk && stk[stk.length - 1] < v) { m[stk.pop()] = v; } stk.push(v); } return nums1.map(e => m[e] || -1); }; ``` ### 方法二 #### Python3 ```python class Solution: def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: m = {} stk = [] for v in nums2[::-1]: while stk and stk[-1] <= v: stk.pop() if stk: m[v] = stk[-1] stk.append(v) return [m.get(x, -1) for x in nums1] ``` #### Java ```java class Solution { public int[] nextGreaterElement(int[] nums1, int[] nums2) { Deque stk = new ArrayDeque<>(); Map m = new HashMap<>(); for (int i = nums2.length - 1; i >= 0; --i) { while (!stk.isEmpty() && stk.peek() <= nums2[i]) { stk.pop(); } if (!stk.isEmpty()) { m.put(nums2[i], stk.peek()); } stk.push(nums2[i]); } int n = nums1.length; int[] ans = new int[n]; for (int i = 0; i < n; ++i) { ans[i] = m.getOrDefault(nums1[i], -1); } return ans; } } ``` #### C++ ```cpp class Solution { public: vector nextGreaterElement(vector& nums1, vector& nums2) { stack stk; unordered_map m; for (int i = nums2.size() - 1; ~i; --i) { while (!stk.empty() && stk.top() <= nums2[i]) stk.pop(); if (!stk.empty()) m[nums2[i]] = stk.top(); stk.push(nums2[i]); } vector ans; for (int& v : nums1) ans.push_back(m.count(v) ? m[v] : -1); return ans; } }; ``` #### Go ```go func nextGreaterElement(nums1 []int, nums2 []int) []int { stk := []int{} m := map[int]int{} for i := len(nums2) - 1; i >= 0; i-- { for len(stk) > 0 && stk[len(stk)-1] <= nums2[i] { stk = stk[:len(stk)-1] } if len(stk) > 0 { m[nums2[i]] = stk[len(stk)-1] } stk = append(stk, nums2[i]) } var ans []int for _, v := range nums1 { val, ok := m[v] if !ok { val = -1 } ans = append(ans, val) } return ans } ``` #### Rust ```rust impl Solution { pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { nums1 .iter() .map(|target| { let mut res = -1; for num in nums2.iter().rev() { if num == target { break; } if num > target { res = *num; } } res }) .collect::>() } } ``` #### JavaScript ```js /** * @param {number[]} nums1 * @param {number[]} nums2 * @return {number[]} */ var nextGreaterElement = function (nums1, nums2) { let stk = []; let m = {}; for (let v of nums2.reverse()) { while (stk && stk[stk.length - 1] <= v) { stk.pop(); } if (stk) { m[v] = stk[stk.length - 1]; } stk.push(v); } return nums1.map(e => m[e] || -1); }; ```