【贪心算法】刷刷刷刷刷刷题(上)

供自己复习,一篇10题左右

  • 1.分发饼干
  • 2.分发糖果
  • 3.跳跃游戏I
  • 4.跳跃游戏II
  • 5.合并区间
  • 6.无重叠区间
  • 7.划分字母区间
  • 8.加油站

1.分发饼干

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

对每个孩子 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。

这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩
仔细阅读题目的要求,你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
所以必须是先遍历胃口(孩子),给再遍历饼干
不能颠倒!!!!

class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int index = s.size() - 1;int result = 0;for(int i = g.size() - 1; i >= 0; i --){if(index >= 0 && g[i] <= s[index]){result  ++;index --;}}return result;}
};

2.分发糖果

老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。

你需要按照以下要求,帮助老师给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。
  • 相邻的孩子中,评分高的孩子必须获得更多的糖果。

那么这样下来,老师至少需要准备多少颗糖果呢?

示例 1:

  • 输入: [1,0,2]
  • 输出: 5
  • 解释: 你可以分别给这三个孩子分发 2、1、2 颗糖果。

先确定右边评分大于左边的情况(也就是从前向后遍历)
再确定左边大于右边的情况,但是此时不能再从前向后遍历了!!

如图的解释,判断左边大于右边,从前向后遍历的时候,得出的candyVec序列是1 2 1 2 1 1 1
如果还是从前向后遍历,判断右边大于左边,就会得到 1 2 1 2 2 2 2 的序列,从评分为5的孩子看来,应该比4高但是却没有得到更多的糖
根本原因就是,图上的3 5 4,判断加不加糖,左和右是岔开的,不能一样的遍历判断
这样逻辑会出问题。
在这里插入图片描述
第二个,就是从后向前遍历的时候,candVec[i]的选取问题,不能直接取candyVec[i + 1] + 1,因为有可能candyVec本身就比他大,再加的话不满足题目要求的最少糖果,所以candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1)

class Solution {
public:int candy(vector<int>& ratings) {vector<int> candyVec(ratings.size(), 1);// 从前向后for (int i = 1; i < ratings.size(); i++) {if (ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;}// 从后向前for (int i = ratings.size() - 2; i >= 0; i--) {if (ratings[i] > ratings[i + 1] ) {candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);}}// 统计结果int result = 0;for (int i = 0; i < candyVec.size(); i++) result += candyVec[i];return result;}
};

3.跳跃游戏I

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false

题目只关心能不能跳到终点,所以不用关系要跳几步,只要最后能覆盖住终点就行

贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点

定义cover为每次能跳的步长,跳完当前步长和,步跳完当前步长后能跳的步长,做对比,取最大的!
cover可能会大于数组长度,所以要及时return!!

class Solution {
public:bool canJump(vector<int>& nums) {int cover = 0;if (nums.size() == 1) return true; for (int i = 0; i <= cover; i++) { cover = max(i + nums[i], cover);if (cover >= nums.size() - 1) return true; }return false;}
};

4.跳跃游戏II

给定一个长度为 n0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

不能真的能跳多远就跳多远,那样就不知道下一步最远能跳到哪里了。
所以真正解题的时候,要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最少步数!

这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖

如果移动下标达到了当前这一步的最大覆盖最远距离了,还没有到终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。

通俗点说,
第一步是要知道当前最远能跳到哪里,这里只需要知道最远能跳到哪里,中间没有操作
第二步是要知道以当前的跳的基础,下一步能跳到哪里,虽然是以当前的跳为基础,但是这里是个范围,在第一步没跳到第一步落地这个范围里面,找到第二步的最大覆盖
更新:当前覆盖的更新,是拿每一次next的值去更

class Solution {
public:int jump(vector<int>& nums) {if(nums.size() <= 1) return 0;int cur = 0;int next = 0;int ans = 0;for(int i = 0; i < nums.size(); i ++){next = max(nums[i] + i, next);if(i == cur){ans ++;cur = next;if(next >= nums.size() - 1) break;}}return ans;}
};

5.合并区间

给出一个区间的集合,请合并所有重叠的区间。

示例 1:

  • 输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
  • 输出: [[1,6],[8,10],[15,18]]
  • 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
class Solution {
public:vector<vector<int>> merge(vector<vector<int>>& intervals) {sort(intervals.begin(), intervals.end(), [](const vector<int> a, const vector<int> b){return a[0] < b[0];});vector<vector<int>> result;result.push_back(intervals[0]);for(int i = 0; i < intervals.size(); i ++){if(intervals[i][0] <= result.back()[1]){ // 区间重叠result.back()[1] = max(intervals[i][1], result.back()[1]);}else{result.push_back(intervals[i]); // 区间不重叠 }}return result;}
};

6.无重叠区间

给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

注意: 可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。

示例 1:

  • 输入: [ [1,2], [2,3], [3,4], [1,3] ]
  • 输出: 1
  • 解释: 移除 [1,3] 后,剩下的区间没有重叠。

按照右边界排序!!!

class Solution {
public:static bool cmp(const vector<int> a, const vector<int> b){return a[1] < b[1];}int eraseOverlapIntervals(vector<vector<int>>& intervals) {if(intervals.size() == 0) return 0;sort(intervals.begin(), intervals.end(), cmp);int end = intervals[0][1];int count = 1;for(int i = 1; i < intervals.size(); i ++){if(intervals[i][0] >= end){count ++;end = intervals[i][1];}}return intervals.size() - count;}
};

7.划分字母区间

字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。

示例:

  • 输入:S = “ababcbacadefegdehijhklij”
  • 输出:[9,7,8] 解释: 划分结果为 “ababcbaca”, “defegde”, “hijhklij”。 每个字母最多出现在一个片段中。 像"ababcbacadefegde", “hijhklij” 的划分是错误的,因为划分的片段数较少。

提示:

  • S的长度在[1, 500]之间。
  • S只包含小写字母 ‘a’ 到 ‘z’

在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。

可以分为如下两步:

  • 统计每一个字符最后出现的位置
  • 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
    在这里插入图片描述
class Solution {
public:vector<int> partitionLabels(string s) {// 更新每个字母出现的最远下标// 区间内更新其中每个字母出现的最远下标,i等于这个下标的时候片段+1int hash[27] = {0};//hash数组里面是不同字母对应的ascll码的最远下标 for(int i = 0; i < s.size(); i ++){hash[s[i] - 'a'] = i;}vector<int> result;int left = 0;int right = 0;for(int i = 0; i < s.size(); i ++){right = max(right, hash[s[i] - 'a']);if(i == right){result.push_back(right - left + 1);left = i + 1;}}return result;}
};

8.加油站

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

直接从全局进行贪心选择,情况如下:

  • 情况一:如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的
  • 情况二:rest[i] = gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。
  • 情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。

首先遍历计算每一个加油站点留下来的rest

然后rest累加,并且同时关注这个累加的curSum是否小于0,小于0就记录给min,当遍历完之后,可以得到curSum的值,还有累加过程中最小的一个和min

如果curSum小于0,情况一
如果min >= 0,情况二
情况三,min的值就有用了,之前记录了最小的和,现在从后往前,一个个加给他,

当从后向前进行遍历时,实际上是在尝试找到一个点,从该点出发(不论是向前还是向后)都能保证剩余油量始终大于等于零。

class Solution {
public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int curSum = 0;int min = 0;for(int i = 0; i < gas.size(); i ++){int rest = gas[i] - cost[i];curSum += rest;if(curSum < min){min = curSum;}}if(curSum < 0) return -1;if(min >= 0) return 0;for(int i = gas.size() - 1; i >= 0; i --){int rest = gas[i] - cost[i];min += rest;if(min >= 0) return i;}return -1;}
};

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

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

相关文章

SERDES高速链路PCB设计的信号完整性考虑

链路包括一个发射模块、一个接收模块以及介于两者之间的所有称为“信道”的部分。在网络和电信设备中&#xff0c;信道通常包括线路卡和背板或中板。假设线性接收器处的波形只是发射波形与信道冲激响应的卷积&#xff0c;如果信道频率响应作为频率的函数是均匀的&#xff0c;则…

数据结构修炼——常见的排序算法:插入/希尔/选择/堆排/冒泡/快排/归并/计数

目录 一、常见的排序算法二、常见排序算法的实现2.1 排序算法回顾2.1.1 冒泡排序2.1.2 堆排序 2.2 直接插入排序2.3 希尔排序2.4 选择排序2.5 快速排序2.5.1 快速排序&#xff08;霍尔法&#xff09;2.5.2 快速排序&#xff08;挖坑法&#xff09;2.5.3 快速排序&#xff08;前…

GJB438C-2021《软件需求规格说明》的一处修订

今日偶见GJB438C-2021附录J《软件需求规格说明》的正文格式。 其中3.3.X.d条中的第2&#xff09;和5&#xff09;中使用了术语“数据元素组合体”&#xff1a; 在上一版本GJB438B-2009中的对应文字是&#xff1a; 我觉得把“包”改为“数据元素组合体”是合适的&#xff0c;其…

手机玩使命召唤21:黑色行动6?GameViewer远程玩使命召唤教程

使命召唤21&#xff1a;黑色行动 6这个第一人称射击游戏&#xff0c;将于10月25号上线&#xff01;如果你是使命召唤的老玩家&#xff0c;是不是也在期待这部新作&#xff1f;其实这个游戏不仅可以用电脑玩&#xff0c;还可以用手机玩&#xff0c;使用网易GameViewer远程就能让…

Termius工具在MAC的使用出现的问题:

Termius工具在MAC的使用出现的问题&#xff1a; 在使用SFTP时&#xff0c;出现不了本地的文件的位置 解决方案&#xff1a; 在Apple store下载的使用不了LOCAL SFTP&#xff0c; 需要在网页上进行下载才可以&#xff1a; 官网下载地址&#xff1a;https://termius.com/down…

Redis简介及其在NoSQL应用开发中的优化策略

Redis简介 REDIS数据库为NOSQL的其中一种&#xff0c;又称为REDIS缓存。 80%的系统瓶颈主要出现在数据库一侧 --(海量并发下&#xff0c;网络、磁盘IO开销会导致数据库性能出现瓶颈) --(海量数据下&#xff0c;数据查找可能需要关联上千张表、遍历数千万的数据、花费几分钟) 为…

python-django-mysql原生sql增删改查搭建搭建web项目

先看我本地的项目结构 1 设置虚拟环境 python -m venv venv .\venv\Scripts\activate 2 在虚拟环境中安装Django 执行 pip install -r requirements.txt asgiref3.8.1 backports.zoneinfo0.2.1 Django3.2 mysqlclient2.2.4 pytz2024.2 sqlparse0.5.1 typing-extensions4.1…

利用AI提升论文写作效率:高效提示词指南

利用AI提升论文写作效率&#xff1a;高效提示词指南 前言1. 论文构思与选题2. 文献综述3. 理论框架和方法论4. 数据分析与结果讨论5. 论文撰写与润色6. 参考文献与引用7. 摘要和关键词结语 前言 在这个信息爆炸的时代&#xff0c;学术研究和论文写作已经成为了知识传播和学术发…

微信小程序文字转语音播报案例

插件申请 在小程序官方申请同声传译插件&#xff0c;地址&#xff1a; mp.weixin.qq.com 引入插件 在app.json中加入 "plugins": {"WechatSI": {"version": "0.3.6","provider": "wx069ba97219f66d99"}},封装…

linux介绍与基本指令

前言 本次博客将会讲解linux的来源历史、linux操作系统的理解以及它的一些基本指令。 1.linux的介绍 linux的来源 linux的来源最初还是要说到unix操作系统的。 1968年&#xff0c;一些来自通用电器公司、贝尔实验室和麻省理工学院的研究人员开发了一个名叫Multics的特殊操作…

10.22 MySQL

存储过程 存储函数 存储函数是有返回值的存储过程&#xff0c;存储函数的参数只能是in类型的。具体语法如下&#xff1a; characteristic 特性 练习&#xff1a; 从1到n的累加 ​​​​​​ create function fun1(n int) returns int deterministic begindeclare total i…

数据结构与算法:贪心算法与应用场景

目录 11.1 贪心算法的原理 11.2 经典贪心问题 11.3 贪心算法在图中的应用 11.4 贪心算法的优化与扩展 总结 数据结构与算法&#xff1a;贪心算法与应用场景 贪心算法是一种通过选择当前最佳解来构造整体最优解的算法策略。贪心算法在很多实际问题中都取得了良好的效果&am…

MATLAB代码优化

MATLAB使用矩阵运算&#xff0c;因此使用矩阵运算速度要远超普通计算。 实验f(x,y)Asin(u0*xv0y)运算速度 代码&#xff1a; function [t, f, g] TASK(A, u0, v0, M, N) % M,N为像素点 tic for x 1:M %采用for循环计算for y 1:Nf(x, y) A * sin(u0 * (x-1) v0 * (y-1));…

ESP8266学习记录

一、接入点模式 NodeMCU可以建立WiFi网络供其它设备连接。当NodeMCU以此模式运行时&#xff0c;我们可以使用手机搜索NodeMCU所发出的WiFi网络并进行连接。 通过以下示例程序&#xff0c;NodeMCU将会建立一个名为我将点燃大海的WiFI。您可以使用手机或电脑连接该WiFi从而实现与…

图片无损放大工具Topaz Gigapixel AI v7.4.4 绿色版

Topaz A.I. Gigapixel是这款功能齐全的图象无损变大运用&#xff0c;应用可将智能机拍摄的图象也可以有着专业相机的高质量大尺寸作用。你可以完美地放大你的小照片并大规模打印&#xff0c;它根本不会粘贴。它具有清晰的效果和完美的品质。 借助AIGigapixel&#xff0c;您可以…

SD-WAN企业组网的应用场景

SD-WAN&#xff08;软件定义广域网&#xff09;能够实现企业不同站点之间的高效互联&#xff0c;确保分支机构、总部、数据中心以及云平台等站点的顺畅通信。本文将探讨从企业的WAN业务需求出发&#xff0c;可以将SD-WAN的组网场景分为哪几类。 SD-WAN的典型组网场景 企业站点之…

Java使用dom4j生成kml(xml)文件遇到No such namespace prefix: xxx is in scope on:问题解决

介绍addAttribute和addNamepsace: addAttribute 方法 addAttribute 方法用于给XML元素添加属性。属性&#xff08;Attributes&#xff09;是元素的修饰符&#xff0c;提供了关于元素的额外信息&#xff0c;并且位于元素的开始标签中。属性通常用于指定元素的行为或样式&#…

【华为HCIP实战课程十七】OSPF的4类及5类LSA详解,网络工程师

一、5类LSA详解 由ASBR产生,描述到AS外部的路由,通告到所有的区域(除了STUB区域和NSSA区域)。 我们在R6设备配置引入直连路由,R6的lo10 属于区域2 interface LoopBack10 ip address 6.6.6.6 255.255.255.255 ospf enable 1 area 0.0.0.2 [R6-ospf-1]import-route dire…

Java | Leetcode Java题解之第502题IPO

题目&#xff1a; 题解&#xff1a; class Solution {public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) {int n profits.length;int curr 0;int[][] arr new int[n][2];for (int i 0; i < n; i) {arr[i][0] capital[i];arr[i][1] profi…

深度学习——线性神经网络(五、图像分类数据集——Fashion-MNIST数据集)

目录 5.1 读取数据集5.2 读取小批量5.3 整合所有组件 MNIST数据集是图像分类中广泛使用的数据集之一&#xff0c;但是作为基准数据集过于简单&#xff0c;在本小节将使用类似但更复杂的Fashion-MNIST数据集。 import torch import torchvision from torch.utils import data fr…