【C++编程能力提升】

代码随想录训练营Day31 | Leetcode 455、376、53

一、455 分发饼干

题目链接:455 分发饼干

核心:贪心策略是用大尺寸饼干匹配大胃口孩子,这样能匹配最多的孩子。
首先需要对输入的两个数组:饼干尺寸数组和孩子胃口数组进行排序;
然后定义一个index从饼干尺寸数组的最后一个元素开始,逐个匹配孩子,需for循环遍历孩子胃口数组,也是从大胃口到小胃口,即从后往前;一旦正确匹配孩子,则index前移,直到遍历完所有孩子。

    int findContentChildren(vector<int>& g, vector<int>& s) {
        int res=0;  //记录满足条件的孩子个数
        //需要先排序才能用大尺寸饼干匹配大胃口孩子,或者小胃口孩子选择小尺寸饼干
        sort(g.begin(),g.end());    
        sort(s.begin(),s.end());
        int index=s.size()-1;   //从大尺寸饼干开始往前遍历
        for(int i=g.size()-1;i>=0;i--)
        {//孩子
            if(index>=0 && s[index]>=g[i])  //饼干
            {//只有在饼干尺寸找到匹配胃口的孩子之后,才前移到上一个尺寸的饼干
                res++;
                index--;
            }
        }
        return res;
    }

二、376 摆动序列

题目链接:376 摆动序列

核心:贪心策略是删除(或不记录)单调坡度的节点(不包括单调坡度两端的节点),这样坡度就存在两个局部峰值。
存在峰值的情况:prediff<0 && curdiff>0 或者prediff>0 && curdiff<0,其中prediff和curdiff分别表示当前元素与前一个元素之差,和后一个元素与当前元素之差。
此外还存在其他特殊情况:
第一,上下坡之间有平坡:即prediff=0 && curdiff!=0或者prediff!=0 && curdiff=0的情况,这里采用前者,那么存在峰值的情况就为:prediff<=0 && curdiff>0 或者prediff>=0 && curdiff<0;
第二,数组首尾两端的处理:默认数组最右端有一个峰值,即令res初始化为1
第三,单调坡存在平坡:比如1,2,2,2,3,4,实际存在的峰值只有2个,因为整个数组都是单调的,实现代码时是通过prediff的更新,即prediff并非每一个节点都需要更新,而是在统计符合峰值的节点数时才更新prediff。

    int wiggleMaxLength(vector<int>& nums) {
        int res=1;  //默认最后一个元素为峰值
        int preDiff=0;  //前一组之差,nums[i]-nums[i-1]
        int curDiff=0;  //当前组之差,nums[i+1]-nums[i]
        for(int i=0;i<nums.size()-1;++i)
        {//遍历数组元素,从0-len-2
            curDiff=nums[i+1]-nums[i];
            if((preDiff>=0 && curDiff<0) || (preDiff<=0 && curDiff>0))
            {//符合峰值、峰谷的要求
                res++;  
                preDiff=curDiff;    //更新前一组元素之差
            }
        }
        return res;
    }

三、53 最大子数组和

题目链接:53 最大子数组和

核心:贪心策略是当前区间元素和(上一个子数组+当前元素之和)为负数时,则舍弃当前元素及之前元素的子数组,从当前元素的下一个开始重新计算子数组和count;一旦子数组和count大于此前所记录的最大子数组和res时,则更新res,最终返回的最大子数组和即为res。
注意:res初始化为INT_MIN,因为如果所有元素均为负数,那么最大子数组和也为负数,此时若res初始化为0,则会出现bug。

    int maxSubArray(vector<int>& nums) {
        int res=INT_MIN; //记录最大子数组和,需设置为最小值,可能存在nums全为负数的情况
        int count=0;    //记录当前区间的数组和
        for(int i=0;i<nums.size();++i)
        {//遍历数组元素
            count+=nums[i]; 
            if(count>res)
                res=count;  //与记录的区间最大值比较,保留区间的最大值
            if(count<=0)
                count=0;    //一旦联系和为负数,则从下一个元素开始重新计算区间和
        }
        return res;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值