贪心-局部最优导致全局最优

一、分发小饼干

胃口值:g[1,3,5,7,9]

饼干大小:s[1,3,4,5,8]

① 每颗饼干尽可能满足胃口最大的男孩(大饼干尽量满足大胃口)--推荐

遍历胃口值,每次循环中,无论是否能满足当前,都进入下次循环

② 每个男孩尽可能有一个最小的饼干去满足(小饼干尽量满足小胃口)

遍历小饼干,每次循环中,无论是否能使用当前小饼干,都进入下次循环

二、寻找最大摆动序列

本题不需要删除掉非摆动点,只统计摆动(峰值)点的数量就好,找到最多的局部的峰值就可以找到最长的摆动序列

1. 处理平坡:不仅要使得prediff和curdiff的正负相反,还需要把=0的情况也算上,即if(prediff>=0 && curdiff<0) || (prediff<=0 && curdiff>0)

注意平坡也分两种,一种是“上平平下”,一种是“上平平上”,为了保证每次递增过程或者递减过程只记录一个位,就在每次成功通过判断时更新prediff = curdiff,从而保证在新的方向上,只在最初记录一次,过程如下图所示,在头脑里跑一遍就懂了

2. 处理首末位:对于末位,如[1,2]  可以认为最后一位永远是一个摆动值,那么遍历时不需要再去遍历最后一个元素了。至于首位,在首位之前虚拟一个相等元素,如[1,1,2]让首位得到处理,也就是另prediff初始值为0,即可实现该效果

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

小结:本题对于连续子过程的处理,和首位元素的处理方法非常值得借鉴

三、最大子序和

题目:

nums = [-2,1,-3,4,-1,2,1,-5,4]

遍历该数组,尽可能使得子数组和最大,

当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。从而推出全局最优:选取最大“连续和”

所以,cur_sum值的变化:[-2,1,-2,4,3,5,6,1,5],其中最大值6 即为答案-最大连续和

    int maxSubArray(vector<int>& nums) {
        int result = INT32_MIN;
        int sum=0;   // 遍历到每个位置时,计算最大连续和
        for(int i=0; i<nums.size(); i++)
        {
            sum+=nums[i];
            result = sum > result ? sum : result;   // 始终记录最大连续和    
            sum = sum < 0 ? 0:sum;     // 当连续和为负值,舍弃

        }
        return result;
    }

听说这题可以用动态规划做,留坑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值