贪心算法(力扣455、376、53)

didi贪心的本质是选择每一阶段的局部最优,从而达到全局最优

LK455.分发饼干

思路:

将孩子序列和饼干序列排序后进行遍历,大饼干满足大孩子(或小饼干满足小孩子)

学习到一个排序函数:

qsort

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

base:指向要排序的数组的首元素的指针;

nmemb:数组中元素的个数;

size:每个元素的大小

compar:比较函数,用于确定元素之间的相对顺序。该函数应该返回一个负数、零或正数,分别表示第一个元素小于、等于或大于第二个元素。

eg:

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

 调用:(此处为升序)

qsort(g, gSize, sizeof(int), cmp);

若为降序:

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

 升序排序的比较函数 int cmp(const void *a, const void *b) 中,ab 的类型是 const void*,也就是通用指针。在执行 *a - *b 时,编译器并不需要知道具体的数据类型,因为减法运算对于整数类型是通用的。

在比较函数中使用 *(int*)b 的目的是为了确保在比较时可以正确解释 b 指针指向的内容为整数类型。在升序排序的情况下,通过 *a - *b 进行比较,不需要手动进行类型转换,因为减法运算是通用的。而在降序排序时,使用 *(int*)b - *(int*)a 进行比较,需要手动将指针转换为整数类型,以确保比较的正确性。

为什么要使用指针:

qsort 函数中,使用指针是因为它是一个通用的排序函数,可以用于排序任意类型的元素。函数签名中的 void* 类型表示通用指针,可以指向任何类型的数据。这种设计使得 qsort 在排序时不依赖于特定的数据类型,从而增强了其通用性。

完整代码:

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



int findContentChildren(int* g, int gSize, int* s, int sSize) {
    if (sSize==0||gSize==0)
        return 0;

    qsort(g, gSize, sizeof(int), cmp);
    qsort(s, sSize, sizeof(int), cmp);

    int count=0;
    int si=sSize-1;//遍历到的饼干数组下标
    int gi=gSize-1;//遍历到的孩子数组下标    

    //从最大的饼干开始与最大的孩子匹配
    for(int i = gi; i >= 0; i--) {
        if(si >= 0 && s[si] >= g[i] ) {
            si--;
            count++;
        }
    }
    return count;
}

LK376.摆动序列

整体思路:

细节处理:

1.有平坡

 2.首尾元素

题中说明若仅有一个元素或两个不相同元素也算作摆动序列。

处理第一个元素:在最前面造一个平坡(令第一个元素的prediff=0)

如:1,2       则1的prediff=0,curdiff=1,满足result++条件。

处理最后一个元素:可默认最后一个元素就是一个摆动,将result初始值设置为1.

也可以写死,判断后给出result。

3.单调坡中有平坡(1,2,2,2,3,4)

解决方案:prediff只记录坡度有改变时的坡度(把prediff=curdiff放在if循环里,不要放在循环外)

当出现摆动的时候再更新prediff

完整代码:

int wiggleMaxLength(int* nums, int numsSize){
    if (numsSize<=1)
        return numsSize;
    int prediff=0;
    int curdiff=0;
    int result=1;

    for (int i=0;i<numsSize-1;i++)
    {
        curdiff=nums[i+1]-nums[i];
        if ((prediff>=0&&curdiff<0)||(prediff<=0&&curdiff>0))
        {
            result++;
            prediff=curdiff;
        }
    }

    return result;

注意:i<numsize-1而不是numsize,否则会发生数组越界。

LK53.最大子数组和

 思路:

若当前连续和为负数,则从下一个数重新开始计数(若为负数,只会拖累后面的数)

代码:

int maxSubArray(int* nums, int numsSize) {
    int result=INT_MIN;

    int count=0;
    for (int i = 0; i < numsSize; i++)
    {
        count=count+nums[i];
        if (count>result)
        {
            result=count;
        }
        if (count<0)
        {
            count=0;
        }
    }
    return result;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值