代码学习记录28----贪心算法

随想录日记part28

t i m e : time: time 2024.03.26



主要内容:今天深入学习贪心算法,接下来是针对题目的讲解:1.柠檬水找零 ;2. 根据身高重建队列;3.用最少数量的箭引爆气球

  • 860.柠檬水找零
  • 406.根据身高重建队列
  • 452. 用最少数量的箭引爆气球


Topic1柠檬水找零

题目:

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
注意,一开始你手头没有任何零钱。
给你一个整数数组 b i l l s bills bills ,其中 b i l l s [ i ] bills[i] bills[i] 是第 i i i 位顾客付的账。如果你能给每位顾客正确找零,返回 t r u e true true ,否则返回 f a l s e false false

输入: b i l l s = [ 5 , 5 , 5 , 10 , 20 ] bills = [5,5,5,10,20] bills=[5,5,5,10,20]
输出: t r u e true true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。
思路:

只需要维护三种金额的数量,5,10和20。
有如下三种情况:
情况一:账单是5,直接收下。
情况二:账单是10,消耗一个5,增加一个10
情况三:账单是20,优先消耗一个10和一个5,如果不够,再消耗三个5

代码如下:

class Solution {
    public boolean lemonadeChange(int[] bills) {
        int num5 = 0;
        int num10 = 0;
        int num20 = 0;
        for (int i = 0; i < bills.length; i++) {
            // 情况1:收到一个5元
            if (bills[i] == 5) {
                num5++;
            }
            // 情况2:收到一个10元
            if (bills[i] == 10) {
                if (num5 > 0) {
                    num5--;
                    num10++;
                } else {
                    return false;
                }
            }
            // 情况3:收到一个20元
            if (bills[i] == 20) {
                if (num10 > 0 && num5 > 0) {
                    num5--;
                    num10--;
                    num20++;
                } else if (num5 > 2) {
                    num5 = num5 - 3;
                    num20++;
                } else {
                    return false;
                }
            }
        }
        return true;
    }
}

时间复杂度 O ( n ) O(n) O(n)
空间复杂度 O ( 1 ) O(1) O(1)



Topic2根据身高重建队列

题目:

假设有打乱顺序的一群人站成一个队列,数组 p e o p l e people people 表示队列中一些人的属性(不一定按顺序)。每个 p e o p l e [ i ] = [ h i , k i ] people[i] = [hi, ki] people[i]=[hi,ki] 表示第 i i i 个人的身高为 h i hi hi ,前面正好有 k i ki ki 个身高大于或等于 h i hi hi 的人。
请你重新构造并返回输入数组 p e o p l e people people 所表示的队列。返回的队列应该格式化为数组 q u e u e queue queue ,其中 q u e u e [ j ] = [ h j , k j ] queue[j] = [hj, kj] queue[j]=[hj,kj] 是队列中第 j j j 个人的属性( q u e u e [ 0 ] queue[0] queue[0] 是排在队列前面的人)。

输入: p e o p l e = [ [ 7 , 0 ] , [ 4 , 4 ] , [ 7 , 1 ] , [ 5 , 0 ] , [ 6 , 1 ] , [ 5 , 2 ] ] people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]] people=[[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
输出: [ [ 5 , 0 ] , [ 7 , 0 ] , [ 5 , 2 ] , [ 6 , 1 ] , [ 4 , 4 ] , [ 7 , 1 ] ] [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
解释:
解释:
编号为 0 的人身高为 5 ,没有身高更高或者相同的人排在他前面。
编号为 1 的人身高为 7 ,没有身高更高或者相同的人排在他前面。
编号为 2 的人身高为 5 ,有 2 个身高更高或者相同的人排在他前面,即编号为 0 和 1 的人。
编号为 3 的人身高为 6 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
编号为 4 的人身高为 4 ,有 4 个身高更高或者相同的人排在他前面,即编号为 0、1、2、3 的人。
编号为 5 的人身高为 7 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新构造后的队列。

思路:

在按照身高从大到小排序后:
局部最优:优先按身高高的 p e o p l e people people k k k 来插入。插入操作过后的 p e o p l e people people 满足队列属性
全局最优:最后都做完插入操作,整个队列满足题目队列属性,局部最优可推出全局最优
在这里插入图片描述
回归本题,整个插入过程如下:
排序完的 p e o p l e : [ [ 7 , 0 ] , [ 7 , 1 ] , [ 6 , 1 ] , [ 5 , 0 ] , [ 5 , 2 ] , [ 4 , 4 ] ] people: [[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]] people[[7,0],[7,1],[6,1],[5,0],[5,2][4,4]]
插入的过程:

  • 插入 [ 7 , 0 ] : [ [ 7 , 0 ] ] [7,0]:[[7,0]] [7,0][[7,0]]
  • 插入 [ 7 , 1 ] : [ [ 7 , 0 ] , [ 7 , 1 ] ] [7,1]:[[7,0],[7,1]] [7,1][[7,0],[7,1]]
  • 插入 [ 6 , 1 ] : [ [ 7 , 0 ] , [ 6 , 1 ] , [ 7 , 1 ] ] [6,1]:[[7,0],[6,1],[7,1]] [6,1][[7,0],[6,1],[7,1]]
  • 插入 [ 5 , 0 ] : [ [ 5 , 0 ] , [ 7 , 0 ] , [ 6 , 1 ] , [ 7 , 1 ] ] [5,0]:[[5,0],[7,0],[6,1],[7,1]] [5,0][[5,0],[7,0],[6,1],[7,1]]
  • 插入 [ 5 , 2 ] : [ [ 5 , 0 ] , [ 7 , 0 ] , [ 5 , 2 ] , [ 6 , 1 ] , [ 7 , 1 ] ] [5,2]:[[5,0],[7,0],[5,2],[6,1],[7,1]] [5,2][[5,0],[7,0],[5,2],[6,1],[7,1]]
  • 插入 [ 4 , 4 ] : [ [ 5 , 0 ] , [ 7 , 0 ] , [ 5 , 2 ] , [ 6 , 1 ] , [ 4 , 4 ] , [ 7 , 1 ] ] [4,4]:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] [4,4][[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]

整体代码如下:

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 先对原先的数组排序
        Arrays.sort(people, (a, b) -> {
            if (a[0] == b[0])
                return a[1] - b[1];
            else
                return b[0] - a[0];
        });
        LinkedList<int[]> queue = new LinkedList<>();
        for (int[] p : people) {
            queue.add(p[1], p);
        }
        return queue.toArray(new int[people.length][]);
    }
}

时间复杂度 O ( n l o g n + n 2 ) O(nlog n + n^2) O(nlogn+n2)
空间复杂度 O ( n ) O(n) O(n)



Topic3用最少数量的箭引爆气球

题目:
有一些球形气球贴在一堵用 X Y XY XY 平面表示的墙面上。墙面上的气球记录在整数数组 p o i n t s points points ,其中 p o i n t s [ i ] = [ x s t a r t , x e n d ] points[i] = [xstart, xend] points[i]=[xstart,xend] 表示水平直径在 x s t a r t xstart xstart x e n d xend xend 之间的气球。你不知道气球的确切 y y y 坐标。一支弓箭可以沿着 x x x 轴从不同点完全垂直地射出。在坐标 x x x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 x s t a r t , x e n d xstart,xend xstartxend, 且满足 x s t a r t ≤ x ≤ x e n d xstart ≤ x ≤ xend xstartxxend,则该气球会被引爆 。可以射出的弓箭的数量没有限制 。 弓箭一旦被射出之后,可以无限地前进。给你一个数组 p o i n t s points points ,返回引爆所有气球所必须射出的最小弓箭数 。

输入: p o i n t s = [ [ 10 , 16 ] , [ 2 , 8 ] , [ 1 , 6 ] , [ 7 , 12 ] ] points = [[10,16],[2,8],[1,6],[7,12]] points=[[10,16],[2,8],[1,6],[7,12]]
输出: 2 2 2
解释:
气球可以用2支箭来爆破:

  • 在x = 6处射出箭,击破气球[2,8]和[1,6]。
  • 在x = 11处发射箭,击破气球[10,16]和[7,12]。

思路:

为了让气球尽可能的重叠,需要对数组进行排序。
如果气球重叠了,重叠气球中右边边界的最小值 之前的区间一定需要一个弓箭。
以题目示例: [[10,16],[2,8],[1,6],[7,12]]为例,如图:(方便起见,已经排序)

在这里插入图片描述

代码实现如下:

class Solution {
    public int findMinArrowShots(int[][] points) {
        if (points.length == 0)
            return 0;
        Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
        int result = 1;
        for (int i = 1; i < points.length; i++) {
            if (points[i][0] > points[i - 1][1])
                result++;
            else {
                points[i][1] = Math.min(points[i][1], points[i - 1][1]);
            }
        }
        return result;
    }
}

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn),因为有一个快排
空间复杂度: O ( 1 ) O(1) O(1),有一个快排,最差情况(倒序)时,需要 n n n 次递归调用。因此确实需要 O ( n ) O(n) O(n) 的栈空间



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

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

相关文章

Jmeter压测实战:Jmeter二次开发之自定义函数

1 前言 Jmeter是Apache基金会下的一款应用场景非常广的压力测试工具&#xff0c;具备轻量、高扩展性、分布式等特性。Jmeter已支持实现随机数、计数器、时间戳、大小写转换、属性校验等多种函数&#xff0c;方便使用人员使用。如果在使用过程中存在和业务强耦合的常用功能函数…

数据结构与算法分析引论1

1.解决问题的算法有很多&#xff0c;但是在输入不同的情况下&#xff0c;不同算法之间的差异也很大&#xff0c;我们总是追求一个更快、更有效的方法。比如说普通的依次查找和二分查找&#xff0c;两者的差异就很大。我们使用大O表示法来表示算法的速度。依次查找就是O(n)&…

vs右键在浏览器中查看报错

vs右键在浏览器中查看报错Visual studio 右键在浏览器中查看报错HTTP错误500.30——ANCM进程内启动失败——.NET Core HTTP Error 500.30 - ANCM In-Process Start Failure - .NET Core HTTP Error 500.30 - ANCM In-Process Start Failure Common solutions to this issue: …

Android Studio 因JDK版本导致编译报错问题处理

一、报错问题提示 Cause: com/android/tools/idea/gradle/run/OutputBuildAction has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0 二、处理方…

论文阅读笔记——Rethinking Pointer Reasoning in Symbolic Execution

文章目录 前言Rethinking Pointer Reasoning in Symbolic Execution12.1、基本情况概述12.2、摘要12.3、引言12.4、方法12.4.1、基本版本12.4.1.1、内存加载和存储12.4.1.2、状态合并 12.4.2、改进12.4.2.1、地址范围选择12.4.2.2、内存清理12.4.2.3、符号化的未初始化内存12.4…

从汇编以及栈帧层面理解内联函数的原理

宏太复杂&#xff0c;所以弄出内联&#xff0c;内联适合小函数&#xff0c;把函数连到程序里面&#xff0c;这样就直接用&#xff0c;不需要调用&#xff0c;但是它占用空间。 C推荐 const和enum替代宏常量 inline去替代宏函数 宏缺点&#xff1a; 1、不能调试 2、没有类型安…

RHCE实验-建立NFS服务器,使的客户端顺序共享数据

第一步&#xff1a;服务端及客户端的准备工作 # 恢复快照[rootserver ~]# setenforce 0​[rootserver ~]# systemctl stop firewalld​[rootserver ~]# yum install nfs-utils -y # 服务端及客户端都安装 第二步&#xff1a;服务端建立共享文件目录&#xff0c;并设置权限…

ClickHouse06-ClickHouse中基础的增删改查

使用数据库&#xff0c;最基础的学习都是增、删、改、查&#xff0c;然后才会去了解基础函数和高阶函数&#xff0c;今天就来看看大火的 ClickHouse 中简单的增删改查怎么写&#xff1f; 创建数据库&#xff1a;create database创建表格&#xff1a;create table修改表格&…

反射率光纤光谱仪检测汽车后视镜反射率

反射率光纤光谱仪是一种用于测量材料表面反射率的精密仪器&#xff0c;它通过光纤传输光信号&#xff0c;并利用光谱仪进行分析&#xff0c;以确定材料的光学特性。反射率光纤光谱仪的工作原理基于相对反射率的计算&#xff0c;它涉及到光源、光纤、光谱仪等关键组件。 后视镜能…

深入了解服务器硬件:从基础知识到实际应用

在当今数字化的社会中&#xff0c;服务器扮演着至关重要的角色&#xff0c;它们是支撑互联网、云计算、大数据等技术发展的基石。而理解服务器硬件的基础知识对于从事IT领域的人员来说至关重要。本文将从服务器硬件的基础知识出发&#xff0c;介绍服务器硬件的组成、作用及其在…

【笔记】OpenHarmony设备开发:搭建开发环境(Ubuntu 20.04,VirtualBox 7.0.14)

参考&#xff1a;搭建开发环境&#xff08;HarmonyOS Device&#xff09; Note&#xff1a;Windows系统虚拟机中Ubuntu系统安装完成后&#xff0c;根据指导完成Ubuntu20.04基础环境配置&#xff08;HarmonyOS Connect 开发工具系列课&#xff09; 系统要求 Windows系统要求&…

刷题日记——济南大学机试

折戟厦大&#xff0c;考虑调剂济南大学&#xff0c;但是更想去的是杭师大&#xff0c;还是刷题&#xff0c;济南大学比厦门大学题目简单很多&#xff0c;因此一篇文章不多分析&#xff0c;直接给出代码&#xff0c;全部采用纯C语言编写并且AC&#xff0c;不用C的stl库。 争取今…

CentOS Stream 8系统配置阿里云YUM源

Linux运维工具-ywtool 目录 一.系统环境二.修改yum文件2.1 CentOS-Stream-AppStream.repo2.2 CentOS-Stream-BaseOS.repo2.3 CentOS-Stream-Extras.repo 三.只有一个配置文件四.其他知识4.1 如果想要启用其他源,修改文件配置:enabled14.2 国内源链接 一.系统环境 CentOS Strea…

DevSecOps平台架构系列-微软云Azure DevSecOps平台架构

目录 一、概述 二、Azure DevOps和黄金管道 2.1 概述 2.2 Azure DevOps架构说明 2.2.1 架构及管道流程图 2.2.2 架构内容 2.2.2.1 Azure Boards 2.2.2.2 Azure Repos 2.2.2.3 Azure Test Plans 2.2.2.4 Azure Pipelines 2.2.2.5 Azure Application Insights 2.2.2.6…

论文阅读---VITC----Early Convolutions Help Transformers See Better

论文题目&#xff1a;Early Convolutions Help Transformers See Better 早期的卷积网络帮助transformers性能提升 vit 存在不合格的可优化性&#xff0c;它们对优化器的选择很敏感。相反现代卷积神经网络更容易优化。 vit对优化器的选择[40](AdamW [27] vs. SGD)&#xff0…

中间件学习--InfluxDB部署(docker)及springboot代码集成实例

一、需要了解的概念 1、时序数据 时序数据是以时间为维度的一组数据。如温度随着时间变化趋势图&#xff0c;CPU随着时间的使用占比图等等。通常使用曲线图、柱状图等形式去展现时序数据&#xff0c;也就是我们常常听到的“数据可视化”。 2、时序数据库 非关系型数据库&#…

机器学习实验作业一----knn算法

机器学习课程的第一个算法knn算法&#xff0c;全称K-Nearest Neighbor&#xff0c;k最邻近算法&#xff0c;为机器学习中最常用&#xff0c;也是最简单的算法。KNN通过测量不同特征值之间的距离来进行分类。本文实现的是较为简单的knn算法&#xff0c;包括测试集&#xff0c;训…

pytorch中关于BF16、FP16的一些操作

文章目录 前提创建BF16和FP16的数据BF16和FP16的二进制存储格式如何根据十进制数得到对应的二进制存储如何根据二进制存储计算对应的十进制数&#xff1f;第一种方法第二种方法 二进制乘法如果是负数怎么办&#xff1f;如何手动计算BF16对应的的二进制存储格式参考链接 前提 好…

湖北汽车工业学院 实验一 关系数据库标准语言SQL

头歌 实验一 关系数据库标准语言SQL 制作不易&#xff01;点个关注呗&#xff01;为大家创造更多的价值&#xff01; 目录 头歌 实验一 关系数据库标准语言SQL**制作不易&#xff01;点个关注呗&#xff01;为大家创造更多的价值&#xff01;** 第一关&#xff1a;创建数据库第…

Chrome/Edge 使用 Markdown Viewer 查看 Markdown 格式文件

Chrome/Edge 使用 Markdown Viewer 查看 Markdown 格式文件 0. 引言1. 安装 Markdown Viewer 插件2. 使用 Markdown Viewer 阅读 Markdown 格式文件 0. 引言 大部分程序员都喜欢 Markdown 格式的文件&#xff0c;这时给一些没有在电脑上安装 Markdown 编辑器的同事分享资料时&…