目录
题目描述
给定两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-greater-element-i
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
- 参考官方题解
- 大致思路:数组1是数组2的子集,遍历一遍数组2,将所有元素的下一个更大元素存储在一个哈希表之中,再遍历数组1,按数组1的元素顺序将下一个更大元素读取到另一个数组上。得到数组2每个元素的下一个更大元素:将当前指向的元素与栈顶元素比较,若栈顶元素小于当前指向的数组2的元素,则将栈顶元素出栈,此时指向的数组2的元素则是其下一个更大元素,一直比较到栈中的元素没有比当前指向数组2的元素小为止,将当前指向元素入栈,指针指向下一个数组2中的元素。如此循环,直到遍历完数组2中的元素,此时栈中剩下的元素皆无下一个更大元素。
- C语言实现
#define maxsize 1000
typedef struct
{
char write;//有无数据的标志位
int key,nextmax;//键值,对应的下一个更大元素
}hashmap;
hashmap* inithashmap(void)//建立并初始化哈希表
{
hashmap* hash=(hashmap *)malloc(maxsize*sizeof(hashmap));
for(int i=0;i<maxsize;i++)
hash[i].write=0;
return hash;
}
void writehash(hashmap* h,int key,int nextmax)//写入新的哈希表项
{
int p=key%maxsize;
while(h[p].write!=0)
{
p=(p+1)%maxsize;//使用线性探测法解决冲突
}
h[p].write=1;
h[p].key=key;
h[p].nextmax=nextmax;
return;
}
int readhash(hashmap* h,int key)//读取对应键值的哈希表值
{
int p=key%maxsize;
while(h[p].key!=key)
{
p=(p+1)%maxsize;
}
return h[p].nextmax;
}
void destroy(hashmap* h)
{
free(h);
}
int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
*returnSize=nums1Size;
int* r_array=(int *)malloc((*returnSize)*sizeof(int));
hashmap* hm=inithashmap();//哈希表
int* stack=(int *)malloc((nums2Size+1)*sizeof(int));//栈
int top=1;//栈指针
if(nums2Size<=0||nums1Size<=0)
{
return r_array;
}
stack[top]=nums2[0];
for(int i=1;i<nums2Size;i++)
{
while(stack[top]<nums2[i]&&top>0)//小于当前比较值则出栈,当前值即为栈顶元素下一个更大元素
{
writehash(hm,stack[top--],nums2[i]);//放入哈希表
}
stack[++top]=nums2[i];//当前值入栈
}
//将剩余的元素写入哈希表,剩余元素没有下一个更大元素
while(top>0)
{
writehash(hm,stack[top--],-1);
}
//读取哈希表的值如数组
for(int i=0;i<nums1Size;i++)
{
r_array[i]=readhash(hm,nums1[i]);
}
free(stack);
destroy(hm);
return r_array;
}