Leetcoder Day27| 贪心算法part01

语言:Java/Go

理论

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

什么时候用贪心?可以用局部最优退出全局最优,并且想不到反例到情况

贪心的一般解题步骤

  • 将问题分解为若干个子问题
  • 找出适合的贪心策略
  • 求解每一个子问题的最优解
  • 将局部最优解堆叠成全局最优解

455.分发饼干

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值  g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

示例  1:

  • 输入: g = [1,2,3], s = [1,1]
  • 输出: 1 解释:你有三个孩子和两块小饼干,3 个孩子的胃口值分别是:1,2,3。虽然你有两块小饼干,由于他们的尺寸都是 1,你只能让胃口值是 1 的孩子满足。所以你应该输出 1。

示例  2:

  • 输入: g = [1,2], s = [1,2,3]
  • 输出: 2
  • 解释:你有两个孩子和三块小饼干,2 个孩子的胃口值分别是 1,2。你拥有的饼干数量和尺寸都足以让所有孩子满足。所以你应该输出 2.

本题的目标是满足更多孩子的胃口,因此大的饼干就优先满足胃口大的孩子,才会确保没有资源浪费。因此局部最优解就是将一定尺寸的饼干尽量喂给与这个尺寸接近胃口的孩子。全局最优就是喂饱尽可能多的孩子。可以先将饼干和胃口数组进行排序,从后向前遍历孩子数组,将大饼干给胃口大的孩子,并且设置一个count统计满足小孩的数量。

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        //先对两个数组进行排序
        Arrays.sort(g);
        Arrays.sort(s);
        int count=0;
        int index=s.length-1;  //饼干数组的下标
        for(int i=g.length-1;i>=0;i--){//先遍历胃口
            if(index>=0 && g[i]<=s[index]){ //再去查找饼干
                count++;
                index--;  //满足条件才会把饼干分配出去,饼干的指针也往前移动
            }
        }
        return count;
    }
}

⚠️注意:如果是从后向前遍历,应该先遍历胃口再遍历饼干,因为这样才不会出现饼干没有合理分配的情况。如果是用小饼干喂饱小胃口,则需要先遍历饼干,再遍历胃口。

376. 摆动序列

如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。

例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3)  是正负交替出现的。相反, [1,4,7,2,5]  和  [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。

给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。

示例 1:

  • 输入: [1,7,4,9,2,5]
  • 输出: 6
  • 解释: 整个序列均为摆动序列。

示例 2:

  • 输入: [1,17,5,10,13,15,10,5,16,8]
  • 输出: 7
  • 解释: 这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。

本题目的是通过删除某些元素,找到最长的摆动子序列并返回其长度。摆动序列如果在一个坐标轴上描点,应该是持续存在n个峰值的序列。如下图:

可以看出需要删除的节点应该是,单调递增/递减时,非端点的节点。此时一个坡度上会有两个局部峰值。全局最优就是找到局部峰值最多的序列。因为本题返回最长子序列的长度,所以不需要进行删除操作,只需要统计局部峰值的个数即可。

计算当前节点和前后节点的关系:prediff(nums[i] - nums[i-1])和curdiff(nums[i+1] - nums[i])

  • prediff < 0 && curdiff > 0 或者 prediff > 0 && curdiff < 0,满足这两个条件的时候,说明nums[i-1],nums[i],nums[i+1]均为峰值。
  • 若遇到平坡,假设上坡后平坡:即prediff > 0 && curdiff = 0,遇到最后一个平坡节点时候,应该是这样的条件:prediff = 0 && curdiff < 0,将这个节点保留,其他平坡的节点都删除。所以当前峰值的条件为(preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)第一个情况就是下坡,第二个情况为上坡。

  • 若遇到单调坡度有平坡,我们只需要在 这个坡度 摆动变化的时候,更新 prediff 就行,这样 prediff 在 单调区间有平坡的时候 就不会发生变化,造成误判。

数组首尾两端:题目中说了,如果只有两个不同的元素,那摆动序列也是 2。例如序列[2,5],如果靠统计差值来计算峰值个数就需要考虑数组最左面和最右面的特殊情况。因为我们在计算 prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i])的时候,至少需要三个数字才能计算,而数组只有两个数字。这里我们可以写死,就是 如果只有两个元素,且元素不同,那么结果为 2。也可以不写死,假设数组最前面还有一个数字,那这个数字应该是什么呢?之前我们在 讨论 情况一:相同数字连续 的时候, prediff = 0 ,curdiff < 0 或者 >0 也记为波谷。那么为了规则统一,针对序列[2,5],可以假设为[2,2,5],这样它就有坡度了即 preDiff = 0

class Solution {
    public int wiggleMaxLength(int[] nums) {
        if(nums.length<=1) return nums.length;
        int curDiff=0;  //记录当前节点和后一个节点的差值
        int preDiff=0; //记录前一个节点和当前节点的差值
        int result=1;
        for(int i=0;i<nums.length-1;i++){
            curDiff=nums[i+1]-nums[i];
            if(preDiff<=0&&curDiff>0 || preDiff>=0 && curDiff<0){//出现峰谷的时候
                    result++;
                    preDiff=curDiff;
            }
        }
        return result;
    }
}

53. 最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

  • 输入: [-2,1,-3,4,-1,2,1,-5,4]
  • 输出: 6
  • 解释:  连续子数组  [4,-1,2,1] 的和最大,为  6。

本题跟上题的区别在于,要求连续。因此不可以进行删除也不可以对数组重排序。本题的直接思路就是两层for循环嵌套,但是时间复杂度太高。可以考虑用贪心算法或动态规划算法。

先尝试找局部最优:比如看前两个元素:-2,1,肯定会先以1作为开头,把1加入到结果中,在sum上加上1,任何负值只会减少和的值。当以1为开头时,又遇到了-3,这时sum变成了负值,所以将1从结果中删除,从3点后面一个元素开始判断,以此类推。还要设置变量maxSum记录最大的和。因此,如果当加上nums[i]时sum变为负数时,就将sum变为0重新计算。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/425352.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据类型和变量

1.数据类型 在Java中数据类型主要分为两类&#xff1a;基本数据类型和引用数据类型。 基本数据类型有四类八种&#xff1a; 1. 四类&#xff1a;整型、浮点型、字符型以及布尔型 2.八种&#xff1a; 整形是分为如上四种 byte short int long 浮点型分为 float 和double …

【Java EE】线程安全的集合类

目录 &#x1f334;多线程环境使用 ArrayList&#x1f38d;多线程环境使⽤队列&#x1f340;多线程环境使⽤哈希表&#x1f338; Hashtable&#x1f338;ConcurrentHashMap ⭕相关面试题&#x1f525;其他常⻅问题 原来的集合类, 大部分都不是线程安全的. Vector, Stack, HashT…

Java---文件,流✨❤️

文章目录 1.遍历文件夹2.遍历子文件夹3.练习流4.以字节流的形式读取文件内容5.以字节流的形式向文件写入数据顶折纠问6 .写入数据到文件 1.遍历文件夹 一般说来操作系统都会安装在C盘&#xff0c;所以会有一个 C:\WINDOWS目录。 遍历这个目录下所有的文件(不用遍历子目录) 找出…

全栈入门,前后端入门--springboot3+vue3制作一个后台管理项目

一&#xff1a;前言 1&#xff1a;因为本人也是全栈初学者&#xff0c;现在主职是公司前端&#xff0c;鉴于当前行业形式&#xff0c;单单只掌握一门语言已经不再吃香&#xff0c;甚至有点危险&#xff0c;35岁危机极大可能提前。作为00后要始终保持危机意识&#xff0c;不至于…

[C++]使用纯opencv去部署yolov9的onnx模型

【介绍】 部署 YOLOv9 ONNX 模型在 OpenCV 的 C 环境中涉及一系列步骤。以下是一个简化的部署方案概述&#xff0c;以及相关的文案。 部署方案概述&#xff1a; 模型准备&#xff1a;首先&#xff0c;你需要确保你有 YOLOv9 的 ONNX 模型文件。这个文件包含了模型的结构和权…

opencv生成一张图片

opencv也可以创造出一张照片&#xff0c;下面就是创造一张照片&#xff0c;并存放到项目文件夹下的示例 #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <vector> using namespace cv…

sql注入之sqli-labs-less-2 数值型报错注入

输入?id1 进行试探,第二关数值型&#xff0c;没有字符串的单引号&#xff0c;所以输入单引号报错&#xff0c; 经试探?id1 order by 5 -- 如果是错误的数值&#xff0c;显示如下&#xff1a; 正确 的为&#xff1a; ?id1 order by 3 -- 进行注入查看回显点&#xff1a; …

个体工商户营业执照怎么在网上年检?

第一步PC端登录国家企业信用信息公示系统&#xff01; 第二步点企业信息填报&#xff01; 第三步选择省份&#xff01; 第四步登陆方式&#xff01; 第五步点左上角年度报告填写&#xff01; 第六步下滑浏览点确认&#xff01; 第七步按照实际情况填写&#xff01; 第八步…

Linux笔记--文件权限

一、相关概念 Linux最优秀的地方之一就在于多人多任务环境。为了让各个使用者有较为保密的文件数据&#xff0c;文件的权限管理尤为重要。 ●文件的可存取身份: owner:文件拥有者 group:文件所属用户组 others:其他人 ●文件权限: r: read&#xff0c;读 文件:是否能查看文件内…

代码随想录刷题笔记 DAY 41 | 整数拆分 No.343 | 不同的二叉搜索树 No.96

文章目录 Day 4101. 整数拆分&#xff08;No. 343&#xff09;<1> 题目<2> 笔记<3> 代码 02. 不同的二叉搜索树&#xff08;No. 96&#xff09;<1> 题目<2> 笔记<3> 代码 Day 41 01. 整数拆分&#xff08;No. 343&#xff09; 题目链接 …

2024.3.1 小项目

1、机械臂 #include <myhead.h> #define SER_IP "192.168.125.32" //服务器端IP #define SER_PORT 8888 //服务器端端口号#define CLI_IP "192.168.68.148" //客户端IP #define CLI_PORT 9999 /…

Mybatis plus扩展功能-Db静态工具

目录 1 前言 2 使用方法 2.1 Db静态工具拥有的部分方法 2.2 举例 1 前言 在我们的服务层中&#xff0c;有时为了实现一个方法需要引入其它的Mapper层方法&#xff0c;但是&#xff0c;这样可能出现循环依赖。虽然Spring已经给我们解决了简单的循环依赖问题&#xff0c;但是…

【书生·浦语大模型实战营】第4节 课后作业

XTuner 大模型单卡低成本微调实战 0. 课程链接1. 课后作业1.2 进阶作业 0. 课程链接 课程链接&#xff1a;https://github.com/InternLM/tutorial/blob/main/xtuner/README.md 1. 课后作业 构建数据集&#xff0c;使用 XTuner 微调 InternLM-Chat-7B 模型, 让模型学习到它是你…

数字化转型导师坚鹏:证券公司数字化思维升级之道

证券公司数字化思维升级之道 ——数字化思维之六脉神剑 课程背景&#xff1a; 很多证券公司存在以下问题&#xff1a; 不知道数字化转型如何改变思维模式&#xff1f; 不清楚需要建立什么样的数字化思维&#xff1f; 不知道如何开展数字化思维提升工作&#xff1f; 课…

Redis小白入门教程

Redis入门教程 1. Redis入门1.1 Redis简介1.2 Redis服务启动与停止1.2.1 Redis下载1.2.2 服务启动命令1.2.3 客户端连接命令1.2.4 修改Redis配置文件 2. Redis数据类型2.1 五种常用数据类型介绍2.1.1 字符串操作命令2.1.2 哈希操作命令2.1.3 列表操作命令2.1.4 集合操作命令2.1…

JWT的原理与隐患

什么是JWT JWT通常由三部分组成&#xff1a;头信息&#xff08;header&#xff09;, 消息体&#xff08;payload&#xff09;和签名&#xff08;signature&#xff09;。 头信息指定了该JWT使用的签名算法 header {"alg":"HS256","typ":"…

9.8分割等和子集(LC416-M)

算法&#xff1a; 可以转换为背包问题&#xff1a; 一个商品如果可以重复多次放入是完全背包&#xff0c;而只能放入一次是01背包&#xff0c;写法还是不一样的。 要明确本题中我们要使用的是01背包&#xff0c;因为元素我们只能用一次。 只有确定了如下四点&#xff0c;才能…

C++_程序流程结构_循环结构_while

while循环结构 作用 满足循环条件&#xff0c;执行循环语句 语法 while (循环条件&#xff09;{循环语句}解释 只要循环条件的结果为真&#xff0c;就执行循环语句 流程图 示例 注意 在执行循环语句时候&#xff0c;程序必须提供跳出循环的出口&#xff0c;否则出现死循…

B083-SpringCloud-eureka ribbon feign hystrix

目录 eureka基础项目准备注册中心的搭建生产者注册到eureka消费者注册到eureka并通过eureka调用生产者eureka集群 服务提供者集群集群以后消费者调用服务的问题ribbon消费者使用ribbon负载均衡赋值负载均衡策略负载均衡优化 feignHystrixHystrix概述Ribbon搭配Hystrix降级处理F…

springboot+vue学生信息管理系统学籍 成绩 选课 奖惩,奖学金缴费idea maven mysql

技术栈 ide工具&#xff1a;IDEA 或者eclipse 编程语言: java 数据库: mysql5.7 框架&#xff1a;ssmspringboot都有 前端&#xff1a;vue.jsElementUI 详细技术&#xff1a;springbootSSMvueMYSQLMAVEN 数据库工具&#xff1a;Navicat/SQLyog都可以学生信息管理系统主要实现角…
最新文章