496——下一个更大元素

题目描述

给定两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在nums2 中的下一个比其大的值。
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1。

这里是引用

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-greater-element-i
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

  1. 参考官方题解
  2. 大致思路:数组1是数组2的子集,遍历一遍数组2,将所有元素的下一个更大元素存储在一个哈希表之中,再遍历数组1,按数组1的元素顺序将下一个更大元素读取到另一个数组上。得到数组2每个元素的下一个更大元素:将当前指向的元素与栈顶元素比较,若栈顶元素小于当前指向的数组2的元素,则将栈顶元素出栈,此时指向的数组2的元素则是其下一个更大元素,一直比较到栈中的元素没有比当前指向数组2的元素小为止,将当前指向元素入栈,指针指向下一个数组2中的元素。如此循环,直到遍历完数组2中的元素,此时栈中剩下的元素皆无下一个更大元素。
  3. 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*sizeof(int));//栈
    int top=-1;//栈指针

    for(int i=0;i<nums2Size;i++)
    {
        while(top>-1&&stack[top]<nums2[i])//小于当前比较值则出栈,当前值即为栈顶元素下一个更大元素
        {
            writehash(hm,stack[top--],nums2[i]);//放入哈希表
        }  
        stack[++top]=nums2[i];//当前值入栈  
    }

    //将剩余的元素写入哈希表,剩余元素没有下一个更大元素
    while(top>-1)
    {
        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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值