贪心算法 part03

文章参考来源代码随想录

134. 加油站

方法一分类讨论:

情况一:如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的

情况二:rest[i] = gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。

情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。

class Solution {
public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int curSum = 0;int min = INT_MAX; // 从起点出发,油箱里的油量最小值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;  // 情况1if (min >= 0) return 0;     // 情况2// 情况3for (int i = gas.size() - 1; i >= 0; i--) {int rest = gas[i] - cost[i];min += rest;if (min >= 0) {return i;}}return -1;}
};

方法二贪心算法 :

从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。(反例可以通过简单的数学推断证明不成立)

局部最优:找到当前和为负数的位置(没油了)清空当前和,找到之后当前和大于零的位置。

全局最优:找到唯一起始位置

这里我们通过每次当前和小于零时,更新目标位置(后一位)并清空当前和直至当前和大于零,以此来找到第一次出现当前和大于零的位置。

class Solution {
public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int cursum=0;//当前和int totalsum=0;//总和int start=0;for(int i=0;i<gas.size();i++){cursum+=gas[i]-cost[i];totalsum+=gas[i]-cost[i];if(cursum<0){start=i+1;cursum=0;}}if(totalsum<0)return -1;return start;}
};

 135. 分发糖果

如果两边一起考虑一定会顾此失彼。

所以这里采用两次遍历

从前往后:找出右大于左的

局部最优1:只要右边评分比左边大,右边的孩子就多一个糖果,全局最优:相邻的孩子中,评分高的右孩子获得比左边孩子更多的糖果

从后往前:找出左大于右的

疑惑点:为什么不能从前向后遍历呢?因为 rating[5]与rating[4]的比较 要利用上 rating[5]与rating[6]的比较结果,所以 要从后向前遍历

如果 ratings[i] > ratings[i + 1],此时candyVec[i](第i个小孩的糖果数量)就有两个选择了,一个是candyVec[i + 1] + 1(从右边这个加1得到的糖果数量),一个是candyVec[i](之前比较右孩子大于左孩子得到的糖果数量)。

因此,局部最优2:取candyVec[i + 1] + 1 和 candyVec[i] 最大的糖果数量,保证第i个小孩的糖果数量既大于左边的也大于右边的。全局最优:相邻的孩子中,评分高的孩子获得更多的糖果。

class Solution {
public:int candy(vector<int>& ratings) {int sum=0;vector<int>candy(ratings.size(),1);for(int i=0;i<ratings.size()-1;i++){if(ratings[i]<ratings[i+1])candy[i+1]=candy[i]+1;}for(int i=ratings.size()-1;i>0;i--){if(ratings[i]<ratings[i-1])candy[i-1]=max(candy[i-1],candy[i]+1);}for(int k:candy)sum+=k;return sum;}
};

860.柠檬水找零

5,10,20

付5直接不用找,付10找5,付20找10+5或者5+5+5

局部最优:优先消耗10(5更通用)去完成本次找零

 全局最优:完成全部账单的找零

class Solution {
public:bool lemonadeChange(vector<int>& bills) {int five=0;int ten=0;int twenty=0;for(int k:bills){if(k==5)five++;if(k==10){if(five<=0)return false;ten++;five--;}if(k==20){if(ten>0&&five>0){ten--;five--;}else if(five>=3)five-=3;else return false;}}return true;}
};

406.根据身高重建队列

本题有两个维度,h和k,看到这种题目一定要想如何确定一个维度,然后再按照另一个维度重新排列

如果两个维度一起考虑一定会顾此失彼

由题意我们这里先确定一个维度排序——h

局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性

全局最优:最后都做完插入操作,整个队列满足题目队列属性

所以这里先按身高排序,身高相同再按k排序(这里可以写一个cmp)

之后取每个元素的k为位置一个一个插进去即可

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

但使用vector是非常费时的,C++中vector(可以理解是一个动态数组,底层是普通数组实现的)如果插入元素大于预先普通数组大小,vector底部会有一个扩容的操作,即申请两倍于原先普通数组的大小,然后把数据拷贝到另一个更大的数组上。

所以使用vector(动态数组)来insert,是费时的,插入再拷贝的话,单纯一个插入的操作就是O(n^2)了,甚至可能拷贝好几次,就不止O(n^2)了。

这里给出改为链表的代码

class Solution {
public:static bool cmp(const vector<int>& a, const vector<int>& b) {if (a[0] == b[0]) return a[1] < b[1];return a[0] > b[0];}vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {sort (people.begin(), people.end(), cmp);list<vector<int>> que; // list底层是链表实现,插入效率比vector高的多for (int i = 0; i < people.size(); i++) {int position = people[i][1]; // 插入到下标为position的位置std::list<vector<int>>::iterator it = que.begin();// 这行代码的作用是声明一个迭代器 it,它的类型是 std::list<vector<int>>::iterator, //这个迭代器用于遍历 que 这个 std::list 容器中的 vector<int> 类型的元素。while (position--) { // 寻找在插入位置it++;}que.insert(it, people[i]);}return vector<vector<int>>(que.begin(), que.end());}
};

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【JAVA练习】力扣860.柠檬水找零

题目&#xff1a; 解题思路&#xff1a; 可能面临3种面额&#xff0c; 5美元&#xff0c;不找还&#xff0c;5美元钞票数量加110美元&#xff0c;找还5美元&#xff0c;5美元钞票数量减1&#xff0c;10美元钞票加120美元&#xff0c;找还15美元&#xff0c;分为一张10美元 一…

Telnet不安全?如何配置使用更安全的STelnet远程登录华为AR1000V路由器?

在上一篇文章中&#xff0c;我们介绍了如何配置一台全新的AR1000V&#xff0c;来实现通过Telnet远程登录设备&#xff08;如何配置使用Telnet远程登录华为AR1000V路由器&#xff1f;&#xff09;。其实&#xff0c;在之前的文章中&#xff0c;我们已经介绍过Telnet是一种不安全…

UE----Ios打包笔记

UE 打包 IOS 软件 1.前期准备 1.1. 首先我们需要 一台装有Xcode 的MAC笔记本&#xff08;知道开机密码 最好是空的笔记本 剩余内存要大 &#xff09; 1.2. 一台IOS手机 1.3. 一个申请了开发者账户的 Apple ID (苹果账号) 知晓账号与密码最好 因为很麻烦 1.4. UE 需要 的 兼…

计算机毕业设计Python轨道交通客流预测分析可视化 智慧交通 机器学习 深度学习 人工智能 爬虫 交通大数据

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

windows10电脑缺少dll文件的解决方案,系统缺少dll修复指南

在使用Windows 10操作系统时&#xff0c;有时会遇到由于缺少某些动态链接库&#xff08;Dynamic Link Library, 简称DLL&#xff09;文件而导致程序无法正常运行的问题。本指南将介绍几种解决此类问题的方法。 什么是DLL文件&#xff1f; DLL文件是Windows系统中的一种特殊类型…

并发编程(15)——基于同步方式的线程安全的栈和队列

文章目录 十四、day141. 线程安全的栈1.1 存在隐患的栈容器1.2 优化后的栈容器 2. 线程安全的队列2.1 基于智能指针的线程安全的队列2.2 不同互斥量管理队首、队尾的队列 十四、day14 在并发编程&#xff08;1&#xff09;并发编程&#xff08;5&#xff09;中&#xff0c;我们…

装箱问题的三种解法

有一个箱子容量为V&#xff08;正整数&#xff0c;0≤v≤20000&#xff09;&#xff0c;同时有n个物品&#xff08;0< n ≤30&#xff09;&#xff0c;每个物品有一个体积&#xff08;正整数&#xff09;。 要求n个物品中&#xff0c;任取若干个装入箱内&#xff0c;使箱子的…

万物可爬(以爬取浏览器井盖图片为例)

我们以爬取 井盖图片 这个链接中的图片为例&#xff1a; 点击F12 并选中其中一张图片 &#xff0c;得到它的信息。具体如下&#xff1a;我们可以编写对应的正则表达式&#xff1a; <img[^>]*src"(.*?)"[^>]*alt"井盖图片 的图像结果"[^>]*&g…

【AI系统】轻量级CNN模型新进展

CNN 模型小型化&#xff08;下&#xff09; 在本文会接着介绍 CNN 模型的小型化&#xff0c;除了第二篇文章提到的三个模型外&#xff0c;在本章节会继续介绍 ESPNet 系列&#xff0c;FBNet 系列&#xff0c;EfficientNet 系列和 GhostNet 系列。 ESPNet 系列 ESPNetV1 ESP…

Day06:缓存持久化

缓存持久化 redis做为缓存&#xff0c;数据的持久化是怎么做的&#xff1f; 在Redis中提供了两种数据持久化的方式&#xff1a;1、RDB 2、AOF 方式一&#xff1a;RDB RDB(Redis Database Backup file)&#xff0c;redis数据备份文件&#xff0c;也叫Redis数据快照&#xff…

msvcr100.dll 文件缺失要怎么解决?msvcr100.dll的多少修复方法分析

面对 msvcr100.dll 文件缺失引发的应用程序运行问题&#xff0c;实际上解决方案并不复杂。本文将提供几种直接有效的修复方法&#xff0c;帮助你迅速恢复文件完整性&#xff0c;确保应用程序能够顺利运行&#xff0c;从而轻松克服这一技术障碍。 一.msvcr100.dll主要特性和功能…

【机器学习】机器学习的基本分类-监督学习-梯度提升树(Gradient Boosting Decision Tree, GBDT)

梯度提升树是一种基于**梯度提升&#xff08;Gradient Boosting&#xff09;**框架的机器学习算法&#xff0c;通过构建多个决策树并利用每棵树拟合前一棵树的残差来逐步优化模型。 1. 核心思想 Boosting&#xff1a;通过逐步调整模型&#xff0c;使后续的模型重点学习前一阶段…

什么是CMMI

CMMI的定义与目的 CMMI&#xff08;Capability Maturity Model Integration&#xff0c;即能力成熟度模型集成模型&#xff09;是一种用于评估和改进组织在软件开发、系统集成、项目管理等方面过程能力的框架。它旨在帮助组织识别其当前的过程能力水平&#xff0c;并提供一个路…

MySQL 入门大全:常用函数

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

动态风景构图技巧和方法

拍摄时要有耐心 当遇到绝佳的拍摄场景时&#xff0c;要放慢脚步&#xff0c;慢慢来&#xff0c;给自己时间去感受它。可能会有一个显而易见的构图方式&#xff0c;你可以先按这个方式拍摄&#xff0c;但随后也要花点时间找找其他可能的构图。 光线会直接影响构图&#xff0c;…

RabbitMq死信队列延迟交换机

架构图 配置 package com.example.demo.config;import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class DeadLetterConfig {public String …

Sringboot项目实现文件上传至linux指定目录

本篇文章讲述一个springboot项目如何实现一个文件上传接口&#xff0c;涉及vsftpd服务、SSH协议以及对linux系统的一些配置。 一、springboot工程部分 本篇文章略过springboot创建过程&#xff0c;具体见之前发过的文章 1.1在pom.xml中添加SFTP&#xff08;SSH 文件传输协议…

电气自动化 基于PLC工业机器人视觉定位及自动码垛系统的设计

摘要 随着我国经济的不断发展&#xff0c;工业机器人将会得到更多的应用&#xff0c;从而达到整个行业的自动化和高速度。由于生产效率的不断提升&#xff0c;对成品进行检验、加工、分级等工作尤为关键。工业机器人是一种高科技的机械设备&#xff0c;它被广泛地运用于焊接、…

云数据库 OceanBase

OceanBase 是阿里巴巴集团自主研发的一款分布式关系型数据库。它采用了分布式架构&#xff0c;能够在大规模、复杂环境下处理海量数据。OceanBase 旨在解决传统数据库在高并发、大规模数据和高可用性场景下的瓶颈&#xff0c;尤其适用于金融、电商、物流等需要高性能、高可靠的…

数据库性能诊断工具DBdoctor 产品介绍

基本信息 DBdoctor是一款专注于数据库性能的生态软件&#xff0c;致力于解决一切数据库性能问题&#xff0c;实现DB AGI。行业首次将eBPF技术聚焦在数据库领域&#xff0c;创新性实现性能可观测。 功能介绍 1.核心功能 SQL审核&#xff0c;性能评估&#xff1a; 独家SQL性能…