题目
给你两个没有重复元素的数组 n u m s 1 nums1 nums1和 n u m s 2 nums2 nums2,其中 n u m s 1 nums1 nums1是 n u m s 2 nums2 nums2的子集。请你找出 n u m s 1 nums1 nums1中每个元素在 n u m s 2 nums2 nums2中的下一个比其大的值。 n u m s 1 nums1 nums1中数字 x x x的下一个更大元素是指 x x x在 n u m s 2 nums2 nums2中对应位置的右边的第一个比 x x x大的元素。如果不存在,对应位置输出 -1 。
解法一:两层循环,时间复杂度 O ( m n ) O(mn) O(mn)
遍历 n u m s 1 nums1 nums1;
第一个while,找到在元素 x x x在 n u m s 2 nums2 nums2中位置;
第二个while,找到离 x x x最近的大于 x x x的元素;
没找到,设为-1;
参考代码C++:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2)
{
int m = nums1.size();
int n = nums2.size();
vector<int> ret(m, -1);
for(int i = 0;i < m; ++i){
int j = 0;
while(nums1[i] != nums2[j]){
++j;
}
while(j < n && nums1[i] >= nums2[j]){
++j;
}
if(j < n){
ret[i] = nums2[j];
}
}
return ret;
}
解法二:栈,时间复杂度 O ( m + n ) O(m+n) O(m+n)
遍历 n u m s 2 nums2 nums2,
使用单调栈辅助1,找到每个元素的下一个最大值
使用map存储( O ( 1 ) O(1) O(1)时间内查询),「key」: n u m s 2 [ i ] nums2[i] nums2[i],「value」: 下一个最大值
遍历 n u m s 1 nums1 nums1,从map中查询其对应的下一个最大值。
参考代码C++
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2)
{
int m = nums1.size();
int n = nums2.size();
stack<int> monoStk;
map<int,int> dict;
for(int i = 0; i < n; ++i){
while(!monoStk.empty() && monoStk.top() < nums2[i]){
int tmp = monoStk.top();
dict[tmp] = nums2[i]; // 找到tmp的下一个大于它的值为nums2[i]
monoStk.pop();
}
monoStk.push(nums2[i]);
}
vector<int> ret(m, -1);
for(int i = 0; i < m; ++i){
if(dict.count(nums1[i])){
ret[i] = dict[nums1[i]];
}
}
return ret;
}
符合单调栈的模式:a. 下一个更大的数;b. 队列中某个元素,找离它左右两边最近的大于(小于)它的元素。c. 柱状图中,找到临近的高于(低于)它的柱子。等等,都可以使用单调栈在一次遍历过程中找到所有元素满足条件的值。 ↩︎