496. 下一个更大元素 I
给定两个 没有重复元素 的数组 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 。
提示:
nums1和nums2中所有元素是唯一的。
nums1和nums2 的数组大小都不超过1000。
题解:
此题和我写的另一题力扣739. 每日温度–暴力法与单调栈有些类似,有兴趣可以看一下。
首先理解题意,我们是要拿着nums1里面的数去nums2里与之相等的数的位置往后去寻找更大的元素。且题目说明了1是2的子集,那么我们如果直接拿着nums2里面的数在原位置之后找更大的元素的话会方便很多,最后再经过1数组的一个选择即可。
那么怎么完成后者的操作呢?
通过分析可知,这又是一个类似“先进后出”的问题,因此我们可以使用栈来解决。
本题是一个单调栈的过程。
(通常是一维数组,要寻找任一元素右边(左边)第一个比自己大(小)的元素一般都会采用单调栈思想。)
即构建一个数组模拟栈,用来模拟我们后者操作的“选择”过程。
先将nums2数组遍历一下,如果栈为空直接入栈,栈不为空时需要分一下两种情况:
1.此时栈外元素大于栈顶元素,则满足题意“下一个最大元素”,所以将此时二者的对应关系通过制造一个哈希映射存储起来,然后让栈顶元素出栈,继续下面的比对。
2.此时栈外元素小于栈顶元素,则直接入栈即可,因为不满足我们的要求.
经过选择后我们可以通过建立哈希映射数组来保存此时nums2数组各元素与其“下一个最大元素”的对应关系,接着由于我们真正要的是nums1这个nums2的子集数组的情况,因此根据存储的哈希映射进行一个选择即可。
代码:
* Note: The returned array must be malloced, assume caller calls free().
*/
int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
int *temp=(int*)malloc(sizeof(int)*nums2Size);//先定义大点为了防止越界,最后可以用return返回真正需要的长度
int hashmap[nums2Size][2];//为nums1的尺寸会越界,因为会碰到不出栈的情况
int k = 0;//哈希映射下标
int top = 0;//栈顶元素下标
for(int i=0;i<nums2Size;i++)//遍历nums2
{
if(top==0)//栈为空
{
temp[top]=nums2[i];
top++;
}
else
{
if(nums2[i]>temp[top-1])//满足情况1
{
hashmap[k][0]=temp[top-1];
hashmap[k][1]=nums2[i];
k++;
top--;//出栈操作
i--;//因为栈外大的元素不是只用一次,他可以用好多次,我们只是让栈顶元素出栈即可,栈外需要再用
}
else
{
temp[top]=nums2[i];
top++;
}
}
}
memset(temp,-1,sizeof(int)*nums1Size);//不能直接sizeof(temp),因为temp是动态数组
//先都填上-1更方便
for(int i=0;i<nums1Size;i++)//遍历nums1
{
int j = 0;//设立个指针来查找我们的哈希映射
while(j<=k)//由前面可知k是有效的哈希映射数组的长度
{
if(nums1[i]==hashmap[j][0])
{
temp[i]=hashmap[j][1];
break;
}
else
{
j++;
}
}
}
*returnSize=nums1Size;//说明一下返回的长度
return temp;
}