LeedCode刷题笔记:最大数量的可修复坑洼(c语言)

又是一道因为不注意基础知识然后出错的题。

题目

题解

最近做题有一个心得,一定要仔细审题!一审题目要求;二审各数值的范围。二审非常重要,这关系到我们最终选择哪种方法解决问题,也关系到解答时是否需要注意数值溢出的问题。举例,如果参数的范围比较小,那么也许我们就可以考虑比较简单、直接的方式求解题目。但是如果这道题参数范围过于大,那么暴力求解就不开行,我们就要考虑别的节省时间和空间的方法。

这道题里,road的最大长度是100000,不算太大,所以我就可以考虑构建一个stack[100000]来保存每个连续坑洼的具体数量。但是如果road的最大长度更大,那我就要考虑一种不会产生空间错误的解法。

这道题的思路,总体分为两步

1.遍历road的,获取每个连续坑洼的具体数量。存于stack里,然后将stack降序排序。例如: x...xx.xxx.....xxxxx。在stack中就存为:{5,3,2,1};

2.从头遍历stack,保证budget>0,做如下操作:

        tem=min(budget-1,stack[i]);

        cnt=cnt+tem;

        budget=budget-(tem+1);

实现的代码如下:

#define Max_lenth 100000

// 比较函数,用于降序排序
int cmp(const void *a, const void *b) {
    return (*(int *)b - *(int *)a);
}

int min(int a, int b) {
    return a < b ? a : b;
}

int maxPotholes(char* road, int budget) {
    if (!strlen(road)) return 0;
    int res = 0, cnt = 0, top = 0;
    int stack[Max_lenth];

    // 初始化 pre 为一个无效字符
    char pre = '\0';

    int road_len = strlen(road);
    // 遍历数组,得到连续的坑洼数量
    for (int i = 0; i < road_len; i++) {
        char c = road[i];
        if (c == 'x') {
            if (top == 0 || pre == '.') {
                stack[top++] = 1;
            } 
            
            if (pre == 'x') {
                stack[top - 1]++;
            }
        }
        pre = c;
    }

    if (top) {
        qsort(stack, top, sizeof(int), cmp);
    }

    for (int i = 0; i < top && budget > 0; i++) {
        int tem = min(budget - 1, stack[i]);
        cnt += tem;
        budget -= 1 + tem;
    }
    return cnt;
}

 踩的坑

排序这里踩了大坑!

我使用的c语言的内置排序方法qsort,它的使用格式为:

qsort(a, n, sizeof(sizeof(a[0]), compare);

a:要排序的数组

n:数组里元素的个数

sizeof(sizeof(a[0]):元素类型的大小

compare:自己定义的比较函数

刚开始我定义的compare函数如下:

int cmp(int a, int b) {
    return b-a;
}

然后我就发现,有的测试用例排序这步有问题,没按照降序排,我就猜测是排序方法出了问题。

改进compare函数,使用标准的写法:cmp 函数现在接受两个 const void* 参数,根据具体需要进行适当的类型转换。如下:

int cmp(const void *a, const void *b) {
    return (*(int *)b - *(int *)a);
}

为什么第一个compare不稳定?

好叭,我暂时没找到具体原因,先记录下来,以后补充。但是得到一个经验:尽量使用标准的写法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我要好好学cs

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

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

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

打赏作者

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

抵扣说明:

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

余额充值