首页 > 编程语言 >leetcode刷题day27|贪心算法Part01(455.分发饼干、376. 摆动序列、53. 最大子序和)

leetcode刷题day27|贪心算法Part01(455.分发饼干、376. 摆动序列、53. 最大子序和)

时间:2024-09-23 19:20:50浏览次数:11  
标签:饼干 小孩 Part01 day27 455 int curDiff result 最优

前言: 贪心的本质选择每一阶段的局部最优,从而达到全局最优。

455.分发饼干

思路:局部最优-大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个;全局最优:喂饱尽可能多的小孩。可以尝试使用贪心策略,先将饼干数组和小孩数组排序,然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。具体实现使用两个指针分别指向两个数组,最大的饼干能满足胃口最大的小孩,小孩数量加一,两个指针同时前移,如果最大的饼干不能满足,则小孩指针前移,继续判断。

代码如下:

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int sNum=s.length-1;
        int child=0;
        for(int i=g.length-1;i>=0;i--){
            if(sNum>=0 && g[i]<=s[sNum]){
                child++;
                sNum--;
            }
        }
        return child;
    }
}

注意:如果是想先喂饱大胃口的小孩,for循环只能是胃口,用下标控制饼干,这样才能满足条件时才移动饼干。

376. 摆动序列

思路:
局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。
整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。
实际操作可以不做删除操作,题目要求最长摆动子序列的长度,只需要统计数组的峰值数量即可。

考虑三种特殊情况:
情况一:上下坡中有平坡:这个时候需要考虑保留平坡左端点还是右端点,如果保留左端点即允许prediff==0。
情况二:数组首尾两端:只有两个元素时,result 初始为 1(默认最右面有一个峰值),此时 curDiff > 0 && preDiff <= 0,那么 result++(计算了左面的峰值),最后得到的 result 就是 2(峰值个数为 2 即摆动序列长度为 2)
情况三:单调坡中有平坡:设置只有在峰值处将curDiff 赋值给preDiff。

代码如下:

class Solution {
    public int wiggleMaxLength(int[] nums) {
        int result=1;
        int preDiff=0;
        int curDiff=0;
        for(int i=1;i<nums.length;i++){
            curDiff=nums[i]-nums[i-1];
            if((preDiff<=0 && curDiff>0 )||(preDiff>=0 && curDiff<0)){
                result++;
                preDiff=curDiff;
            }
        }
        return result;
    }
}

53. 最大子序和

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

代码如下:

class Solution {
    public int maxSubArray(int[] nums) {
        int result=Integer.MIN_VALUE;
        int sum=0;
        for(int i=0;i<nums.length;i++){
            sum+=nums[i];
            result=Math.max(result,sum);
            if(sum<=0){
                sum=0;
            }
        }
        return result;
    }
}

注意只有负数的情况。

总结:目前来看贪心算法的代码并不难,但是难在想到什么是局部最优?怎么达到局部最优?

标签:饼干,小孩,Part01,day27,455,int,curDiff,result,最优
From: https://blog.csdn.net/m0_51007517/article/details/142463755

相关文章

  • leetcode刷题day22|回溯算法Part01( 77. 组合 、216. 组合总和 III、17.电话号码的字母
    前言:回溯是递归的副产品,只要有递归就会有回溯,回溯函数也就是递归函数。回溯是暴力穷举解法,效率并不高。但一些问题只能使用回溯来解决。回溯法,一般可以解决如下几种问题:组合问题:N个数里面按一定规则找出k个数的集合切割问题:一个字符串按一定规则有几种切割方式子集问题:一......
  • Springboot基于Java对运动心跳数据分析系统设计与实现455j4(程序+源码+数据库+调试部署
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、研究背景与意义随着健康意识的提升,运动已成为现代人生活的重要组成部分。心跳数据作为反映人体健康状态的重要指标,在运动过程中尤为重要。然而......
  • Day 19 回溯法part01| LeetCode 77.组合,216. 组合总和 III,17. 电话号码的字母组合
    理论基础回溯法(回溯搜索法)回溯函数就是递归函数本质是穷举解决的问题组合问题(不强调元素顺序,需去重)切割问题子集问题:一个N个数的集合里有多少符合条件的子集排列问题(强调元素顺序)棋盘问题:N皇后回溯法模板(可抽象为树形结构——N叉树来解决问题)递归返回值以及......
  • 洛谷P4550 收集邮票 题解 期望DP
    题目链接:https://www.luogu.com.cn/problem/P4550解题思路:定义状态\(f_i\)表示目前已经取到\(i\)种邮票的情况下,取完所有\(n\)很明显,\(f_n=0\),因为此时已经取完了\(n\)如果当前已经取到了\(i\)有\(\frac{i}{n}\)的概率取到现有的邮票(此时仍然拥有\(i\)有\(1-\frac{i......
  • P4551 最长异或路径(树上前缀异或01-trie)
    #include<bits/stdc++.h>usingnamespacestd;#definexfirst#defineysecondtypedefpair<int,int>PII;typedeflonglongll;typedefunsignedlonglongull;typedefunsignedintuint;typedefvector<string>VS;typedefvector<int>......
  • NOIP2024集训Day27 DP常见模型4 - 树形
    NOIP2024集训Day27DP常见模型4-树形E.[COCI2014-2015#1]Kamp首先只考虑一个点,发现如果回到原来位置是比较好搞的,就每次走完子树的里面要的就上来,如果子树里面没有要走的就不走。(大概是\(f_x=\sumf_y+2\cdote_x\),因为要走过去走回来,注意\(y\)要保证子树里面有人)......
  • 【题解】Solution Set - NOIP2024集训Day27 树形 dp
    【题解】SolutionSet-NOIP2024集训Day27树形dphttps://www.becoder.com.cn/contest/5521「HDU4661」MessagePassing「BZOJ3935」Rbtree「ARC101E」RibbonsonTree「AGC034E」CompleteCompress「COCI2014.10」Kamp「SCOI2015」小凸玩密室「AGC008F」Black......
  • leetcode刷题day13|二叉树Part01(递归遍历、迭代遍历、统一迭代、层序遍历)
    递归遍历思路:使用递归的方式比较简单。1、递归函数的传参:因为最后输出一个数组,所以需要传入根节点和一个容器,本来想写数组,但发现长度不能确定,所以选择list。2、终止条件:当访问的节点为空时,return3、递归函数的逻辑:先访问一个节点,递归访问其他节点144.二叉树的前序遍历......
  • 【P4552】IncDec Sequence
    因为前缀和/差分学习的时候就不熟,所以特选本题作为训练作为一道差分题,本题的思路也是特别的绕,首先进行基础知识的复习【差分】简单来说就是两个数的差,b[i]=a[i]-a[i-1]把序列a的区间[l,r]+d的话,差分序列b则进行以下变化:   b[l]+d,b[r+1]-d前置知识大概就这些,下面进行题......
  • 【代码随想录Day13】二叉树Part01
    理论基础文章讲解:代码随想录二叉树节点的定义:publicclassTreeNode{intval;TreeNodeleft;TreeNoderight;TreeNode(){}TreeNode(intval){this.val=val;}TreeNode(intval,TreeNodeleft,TreeNoderight){this.val......