题目来源于leetcode,解法和思路仅代表个人观点。传送门。
难度:简单
时间:10min
题目
给你两个 没有重复元素 的数组 nums1
和 nums2
,其中nums1
是 nums2
的子集。
请你找出nums1
中每个元素在 nums2
中的下一个比其大的值。
nums1
中数字 x
的下一个更大元素是指 x
在 nums2
中对应位置的右边的第一个比 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
nums1
和nums2
中所有整数
互不相同nums1
中的所有整数同样出现在nums2
中
进阶: 你可以设计一个时间复杂度为 O(nums1.length + nums2.length)
的解决方案吗?
思路
- 暴力解。这就不写了。
- 单调栈+哈希表。
单调栈+哈希表
其实这是一类题——单调栈。所以记录一下。
识别关键字:
下一个,更大、更小
因为,
nums1
是nums2
的子集。
nums1
和nums
都是无序的。
结果求的是nums1中所有元素的下一个更大的元素。
那么,
我们需要使用一个map
记录nums1
元素的下一个更大的元素。
而且,使用单调栈,我们可以求出nums2
中所有元素的下一个更大元素。
单调栈运行过程(求下一个更大的数):
对于nums2
的所有元素:
- 如果栈为空,入栈
当前元素
。 - 如果栈不为空,
栈顶元素
与当前元素
比较。
- 如果
栈顶元素
>=当前元素
入栈当前元素
。 - 如果
栈顶元素
<当前元素
(当前元素
就是,栈顶元素
的下一个更大的元素)
执行循环,出栈所有比当前元素
小的元素(其下一个更大的元素都是当前元素
)。
代码
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 n1为nums1
的长度, n 2 n_2 n2为nums2
的长度。 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 n1为nums1
的长度, n 2 n_2 n2为nums2
的长度。 O ( n 1 ) O(n_1) O(n1)用于哈希表, O ( n 2 ) O(n_2) O(n2)用于单调栈。