题目描述
给定两个没有重复元素的数组 nums1
和 nums2
,其中 nums1
是 nums2
的子集。找到 nums1
中每个元素在 nums2
中的下一个比其大的值。
nums1
中数字 x 的下一个更大元素是指 x 在 nums2
中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1。
样例
输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:
对于 nums1 中的数字 4,你无法在第二个数组中找到下一个更大的数字,因此输出 -1。
对于 nums1 中的数字 1,第二个数组中数字1右边的下一个较大数字是 3。
对于 nums1 中的数字 2,第二个数组中没有下一个更大的数字,因此输出 -1。
输入:nums1 = [2,4], nums2 = [1,2,3,4].
输出:[3,-1]
解释:
对于 nums1 中的数字 2,第二个数组中的下一个较大数字是 3。
对于 nums1 中的数字 4,第二个数组中没有下一个更大的数字,因此输出 -1。
注意
nums1
和nums2
中所有元素是唯一的。nums1
和nums2
的数组大小都不超过 1000。
算法
(哈希表 + 单调栈) $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;
}
};
我感觉貌似看到一个更简练点的方法
大哥你话痨么。。
而且有人还说这个在google 面试中遇到过,增加了我刷这题的动力
google 了一下,明白了,原来就是栈里面的元素是单调的
单调栈是什么意思哇,不懂
好了,我要来看这个高级的解法了。
我只想到了hash表,存好位置, 然后再从那个位置往后找比它大的,虽然比brute force 好一点,但是还是要挨个找就觉得不太开心
所以用单调栈来预处理优化
brute force 太可怕的样子
我天,这是easy 题么,我一看一点想法都木有
The length of both nums1 and nums2 would not exceed 1000. 这个 1000 说明了什么哇? 每次这种提示,我都不知道有什么深层含义
Find all the next greater numbers for nums1’s elements in the corresponding places of nums2. 好绕的题目
而且都496 题,为什么选这么靠后的题目哇
我跟你们说,我一看到这种不熟悉的题目就有种不想看的冲动