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.mzph.cn/news/707987.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux系统化学习】信号概念和信号的产生

目录 信号的概念 从生活中的例子中感知信号 前台进程和后台进程 前台进程 后台进程 操作系统如何知道用户向键盘写入数据了&#xff1f; 进程如何得知自己收到了信号&#xff1f; 信号捕捉 signal函数 Core Dump&#xff08;核心转储&#xff09; 信号产生的方式 通…

黑马c++ STL部分 笔记(2) string容器

char*是指针 string是类&#xff0c;类内部封装了char*&#xff0c;管理这个字符串&#xff0c;是一个char*型的容器 函数&#xff1a;find,copy,delete,replace,insert等 1.构造string // string的构造方式&#xff1a; // 1 string() 创建一个空字符串 string str // 2 s…

LeetCode 刷题 [C++] 第102题.二叉树的层序遍历

题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 题目分析 题目中要求层序遍历二叉树&#xff0c;即二叉树的广度优先搜索(BFS)。BFS一般使用队列的先入先出特性实现&#…

react倒计时功能

目录 类组件写法 函数组件写法&#xff1a; demo: 手机获取验证码登录&#xff08;验证码60秒倒计时&#xff09; react倒计时5 秒 React中的倒计时可以通过使用setInterval()函数来实现。下面是一个示例代码&#xff1a; 类组件写法 import React from react; import { But…

【Docker】狂神说

图片后补 官网&#xff1a; https://www.docker.com/ Docker概述 Docker为什么出现 原因&#xff1a;环境配置不能跨平台 方案 传统方式&#xff1a;jar&#xff08;开发人员&#xff09; 部署&#xff08;运维人员&#xff09; 解决方式&#xff1a;开发打包上线一套流程 …

推荐几个css+js特效网站

CodePen&#xff08;https://codepen.io/&#xff09;&#xff1a;CodePen不仅仅是一个CSS编辑器&#xff0c;它也是一个广受欢迎的JavaScript特效展示平台。你可以在CodePen上浏览和搜索其他开发者创建的各种JavaScript特效&#xff0c;从而获得灵感和学习如何实现不同的效果。…

【算法集训】基础算法:基础排序 - 选择排序

从上一学期期末考完之后就鸽了&#xff0c;真的惭愧&#xff0c;还想着期末考完就开始呢&#xff0c;结果考驾照完了后又有学校项目要忙活。终于是拖到开学了哈哈&#xff0c;虽然现在事情也比较多&#xff0c;但是总归是要开始的&#xff0c;不然马上就要拖延症晚期了&#xf…

设计模式:结构型模式

1. 适配器模式 (Adapter Pattern) 适配器模式是一种结构型设计模式&#xff0c;旨在将一个类的接口转换成客户端所期待的另一个接口&#xff0c;从而使原本由于接口不兼容而无法一起工作的类能够协同工作。适配器模式通常用于需要复用现有类但其接口与要求不匹配的情况。 1.1…

Qt SQLite的创建和使用

重点&#xff1a; 1.SQLite创建数据库内容方法 链接&#xff1a;SQLite Expert Personal的简单使用-CSDN博客 2.和数据库进行链接方法 QSqlDatabase DB; //数据库连接bool MainWindow::openDatabase(QString aFile) {DBQSqlDatabase::addDatabase("QSQLITE"); /…

使用uniapp开发时自定义tabbar

预览图&#xff1a; 一、配置page.jsong中的tabbar&#xff08;这一步是必须的&#xff0c;因为我们在使用uni.switchTab()时必须要用到&#xff09; "tabBar": {"list": [{"pagePath": "pages/index/index","iconPath": &…

java回顾总结--代理模式

目录 一、代理模式1.1 静态代理示例 1.2 动态代理示例 二、总结 一、代理模式 1.1 静态代理 代理模式给某一个对象提供一个代理对象&#xff0c;并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。比如你按照小卡片上的电话打过去寻求服务&#…

C# 学习第四弹——字符串

一、char类型的使用 字符使用单引号&#xff0c;单个字符 转义字符是一种特殊的字符变量&#xff0c;以反斜线开头&#xff0c;后跟一个或多个字符。 输出多级目录可以使用 二、字符串的声明和初始化 1、引用字符串常量 引用字符串常量初始化——字符使用单引号&#xff0…

加密与安全_探索常用编码算法

文章目录 概述什么是编码编码分类ASCII码 &#xff08;最多只能有128个字符&#xff09;Unicode &#xff08;用于表示世界上几乎所有的文字和符号&#xff09;URL编码 &#xff08;解决服务器只能识别ASCII字符的问题&#xff09;实现&#xff1a;编码_URLEncoder实现&#xf…

K8S常用kubectl命令汇总(持续更新中)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

【Prometheus】基于Altertmanager发送告警到多个接收方、监控各种服务、pushgateway

基于Altertmanager发送报警到多个接收方 一、配置alertmanager-发送告警到qq邮箱1.1、告警流程1.2、告警设置【1】邮箱配置【2】告警规则配置【3】 部署prometheus【4】部署service 二、配置alertmanager-发送告警到钉钉三、配置alertmanager-发送告警到企业微信3.1、注册企业微…

量子算法入门—4.量子比特与量子门(1)

1.量子比特 经典比特和量子比特 经典比特只有0、1两种取值&#xff0c;非黑即白&#xff0c;有n位即 2 n 2^n 2n种可能量子比特使用0、1的量子态描述量子比特的状态&#xff0c;可以通过线性组合形成新的量子态&#xff0c;就像光谱可以调节成分 引入线代记法&#xff0c;0、…

ARK:《BIG IDEAS 2024》

Cathie Wood所带领的方舟投资&#xff08;ARK&#xff09;发布了年度重磅研究报告《BIG IDEAS 2024》&#xff0c;该报告指出人工智能、公共区块链、多组学测序、能源存储和机器人技术这五大板块的融合将带来全球经济活动的改变。 这五个创新平台正在融合并定义这个技术时代&am…

92. 递归实现指数型枚举 刷题笔记

思路 dfs 考虑选或者不选每个位置 用0表示未考虑 1表示选 2表示不选 用u表示搜索状态 u>n时 已经搜到底层了 需要输出当前方案 遍历 如果选了则输出 #include<iostream> using namespace std; int n; const int N16; int st[N]; void dfs(int u){ //u来记…

Git自动忽略dll文件的问题

检查了半天发现是sourcetreee的全局忽略文件导致&#xff0c; 从里面删除dll即可。 我是干脆直接删了全局忽略&#xff0c;太恶心了&#xff0c;如下&#xff1a; #ignore thumbnails created by windows Thumbs.db #Ignore files build by Visual Studio *.exe .vsconfig .s…

fastAdmin表格列表的功能

更多文章&#xff0c;请关注&#xff1a;fastAdmin后台功能详解 | 夜空中最亮的星 FastAdmin是一款基于ThinkPHP5Bootstrap的极速后台开发框架。优点见开发文档 介绍 - FastAdmin框架文档 - FastAdmin开发文档 在这里上传几张优秀的快速入门图: 一张图解析FastAdmin中的表格列…