leetcode简单/中等题-单调栈问题(C语言)

1.[496]下一个更大元素I

解题记录:
1.这道题可以用暴力解法,每一个nums1的元素都遍历一次nums2的元素,时间复杂度为O(len1*len2)。
2.这一篇博主要是学习单调栈问题的解法,利用栈的特点,定义单调栈,当新元素的值大于栈顶元素的值的时候,将栈顶元素弹出,并记录在哈希表中,栈顶元素为索引值(题目中给出元素最大为10^4,因此哈希表空间可以设为10000的大小),新元素为value值,也就是下一个更大元素。
3.当新元素小于栈顶元素的时候,可以直接入栈,这样形成的栈为单调递增栈。最后当nums2没有元素可以入栈的时候,栈中的元素都没有下一个更大的值了,可以直接出栈并将哈希表中对应值设置为-1。
4.最后只需要查找哈希表索引对应的值即可得到下一个更大元素。这样的时间复杂度为O(len1+len2)。

C语言代码:

int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    int i, top = -1;
    int *res = (int*)malloc(sizeof(int) * nums1Size);
    int *stack = (int*)malloc(sizeof(int) * nums2Size); //单调栈
    int *hashmap = (int*)malloc(sizeof(int) * 10000); //以nums2元素为索引的哈希表
    //遍历数组2,记录每个元素的下一个更大元素
    for (i = 0; i < nums2Size; i++)
    {
        if (top == -1) //如果为空栈,直接入栈
            stack[++top] = nums2[i];
        else{
            while (top >= 0)
            { //只要新元素大于栈顶元素,则出栈且记录进哈希表
                if (nums2[i] > stack[top])
                    hashmap[stack[top--]] = nums2[i];
                else
                    break;
            }
            //不管是弹栈后记录进哈希表,还是可以直接入栈,都需要把新元素入栈
            stack[++top] = nums2[i];
        }
    }
    while (top >= 0) //把栈中剩余元素的哈希表值设为-1
        hashmap[stack[top--]] = -1;
    for (i = 0; i < nums1Size; i++)
        res[i] = hashmap[nums1[i]];
    *returnSize = nums1Size;
    return res;
}

2.[503]下一个更大元素II

解题记录:
1.本题和上一题非常相似,但区别就在于是循环数组,后面的元素可以找到在其之前的元素作为下一个更大值,所以需要遍历两次。
2.此题在上一题上做了优化,因为题目没有给出数值小于10000这样的限制条件,因此直接记录了数组下标值进行比较,毕竟也不需要拿另一个数组进行依次查找。
3.当新元素小于栈顶元素的时候,可以直接入栈,这样形成的栈为单调递增栈。由于要遍历两次,就不可以最后再将栈中元素对应返回-1,会覆盖原值,所以就用memset进行初始赋值。
4.至于为什么memset(res,-1,sizeof(res))会报错,我还没想明白,等一个大佬解答。

C语言代码:

int* nextGreaterElements(int* nums, int numsSize, int* returnSize){
    *returnSize = numsSize;
    if (numsSize == 0)
        return NULL;
    int i, top = -1;
    int *res = malloc(sizeof(int) * numsSize);
    int *stack = (int*)malloc(sizeof(int) * (2 * numsSize - 1)); //单调栈
    memset(res, -1, sizeof(int) * numsSize); //赋初值
    //遍历数组,记录每个元素的下一个更大元素
    for (i = 0; i < 2 * numsSize - 1; i++)
    {
        int index = i % numsSize; //循环遍历下标
        if (top == -1) //如果为空栈,直接入栈
            stack[++top] = index;
        else{
            while (top >= 0)
            { //只要新元素大于栈顶元素,则出栈且记录进哈希表
                if (nums[index] > nums[stack[top]])
                    res[stack[top--]] = nums[index];
                else
                    break;
            }
            //不管是弹栈后记录进哈希表,还是可以直接入栈,都需要把新元素入栈
            stack[++top] = index;
        }
    }
    //由于本题是扫描两轮,所以会重复入栈,不能直接操作,还是要用memset定义初值
    // while (top >= 0) //把栈中剩余元素的哈希表值设为-1
    //     res[stack[top--]] = -1;
    return res;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一米三呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值