题目描述:
You are given two arrays (without duplicates) nums1
and nums2
where nums1
’s elements are subset of nums2
. Find all the next greater numbers for nums1
's elements in the corresponding places of nums2
.
The Next Greater Number of a number x in nums1
is the first greater number to its right in nums2
. If it does not exist, output -1 for this number.
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2].
Output: [-1,3,-1]
Explanation:
For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.
For number 1 in the first array, the next greater number for it in the second array is 3.
For number 2 in the first array, there is no next greater number for it in the second array, so output -1.
Example 2:
Input: nums1 = [2,4], nums2 = [1,2,3,4].
Output: [3,-1]
Explanation:
For number 2 in the first array, the next greater number for it in the second array is 3.
For number 4 in the first array, there is no next greater number for it in the second array, so output -1.
Note:
- All elements in
nums1
andnums2
are unique. - The length of both
nums1
andnums2
would not exceed 1000.
要完成的函数:
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums)
说明:
1、给定两个vector,比如[3,2]和[2,4,3,1],第一个vector是第二个的子集。要求输出第二个vector中比第一个vector中某个元素大,并且位置上也在其右边的数。要是没找到的话,输出-1。
比如我们给出的例子中,3的next greater element没有,所以我们输出-1。2的next greater element是4,所以输出4。
2、理解题意之后,一般想法是双重循环。
我们可以设定第一个vector为vector1,第二个为vector2。
对于每个vector1中的元素,遍历vector2,找到其位置,在其位置右边继续找,直到找到比它大的数值。
双重循环,这道题可解。
代码如下:
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums)
{
vector<int>::iterator iter;
vector<int>res;
for(int i=0;i<findNums.size();i++)
{
iter=find(nums.begin(),nums.end(),findNums[i]);//找到位置
iter++;
while(iter!=nums.end())//循环处理,直到找到比它大的数
{
if(*iter>findNums[i])
{
res.push_back(*iter);
break;
}
else
iter++;
}
if(iter==nums.end())//边界情况处理
res.push_back(-1);
}
return res;
}
上述代码实测13ms,beats 45.84% of cpp submissions。
3、改进:
双重循环实在太浪费信息了。比如[8,7,1,2,3,4,5,6,9,10],我们要找8的next greater element,要比较中间的1/2/3/4/5/6,才能到9;要找7的next greater element,也要比较中间的1/2/3/4/5/6。我们之前比较过一次,但这些信息完全没有被利用到,又重复比较了一次。
我们可以从左边找起,把那些找到了对应值(也就是next greater element)的删去,然后停留在原本vector2中的,可以想到,是一个下降的vector。
在评论区中参考了大神的代码,自己修改了一下,增加了注释,分享给大家。
代码如下:
vector<int> nextGreaterElement(vector<int>& findNums, vector<int>& nums)
{
stack<int> s1;//存储还没有找到对应值的数
unordered_map<int, int> m1;//建立对应表
for (int i=0;i<nums.size();i++) //对每个新的数进行处理
{
while (s1.size() && s1.top() < nums[i])
{
m1[s1.top()] = nums[i];
s1.pop();
}
s1.push(nums[i]);
}
vector<int> res;
for (int i=0;i<findNums.size();i++)
res.push_back(m1.count(findNums[i]) ? m1[findNums[i]] : -1);
return res;
}
这份代码其实建立了所有能找到next greater element的元素的对应表。
我们当然也可以不用栈来存储,理解起来会更加直接。只不过使用栈使得代码更好写。
上述代码实测11ms,beats 84.93% of cpp submissions。
的确是很优秀的做法。