代码随想录算法训练营第三十五天| 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球

本文主要是介绍代码随想录算法训练营第三十五天| 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目与题解

860.柠檬水找零

题目链接:860.柠檬水找零

代码随想录题解:​​​​​​​860.柠檬水找零

视频讲解:贪心算法,看上去复杂,其实逻辑都是固定的!LeetCode:860.柠檬水找零_哔哩哔哩_bilibili

解题思路:

        从现实实际的角度出发,为了让手里的零钱尽可能的零碎,以备不时之需,需要找钱时肯定尽量能先找大的就找大的。这道题其实限制颇多,给解题降低了不少难度。

        首先,每个顾客只买一份柠檬水,意味着每个顾客每次消费的金额固定,为5美金。其次,顾客每次只会给5,10,20美金的面额,所以对应的情况是不需要找钱,找5美金,和找15美金。前两种的情况对应的找钱都是固定的,只有找15美金时可能有两种情况:找10+5或5*3。为了手里有更多5美金的零钱,优先找10+5的。代码如下

class Solution {public boolean lemonadeChange(int[] bills) {int[] changes = new int[2];for (int i = 0; i < bills.length; i++) {if (bills[i] == 5) {changes[0]++;} else if (bills[i] == 10) {if (changes[0] > 0) {changes[0]--;changes[1]++;} else {return false;}} else {if (changes[1] > 0 && changes[0] > 0) {changes[0]--;changes[1]--;} else if (changes[0] >= 3) {changes[0] -= 3;} else {return false;}}}return true;}
}

看完代码随想录之后的想法 

        这题其实就是现实的模拟题,基本上也没有什么算法可言,就是把想法写下来。由于这里只需要算5美金和10美金的两种剩余零钱情况,可以不需要用数组,换成普通变量记录,效率更高。

遇到的困难

        无

406.根据身高重建队列

题目链接:406.根据身高重建队列

代码随想录题解:​​​​​​​406.根据身高重建队列

视频讲解:贪心算法,不要两边一起贪,会顾此失彼 | LeetCode:406.根据身高重建队列_哔哩哔哩_bilibili

解题思路:

        首先根据身高进行降序排列,如果身高相同的,根据k降序排列。这样做的原因是,身高排序问题本质是一种插入排序,所以每插入一个新的,要保证原来的顺序不受影响。由于身高高的k值不受身高低的k值影响,所以排序的第一个key必然是身高。当二者身高相同时,k值越大的,肯定排的越后,所以优先插入k值小的。

        二维排序结束后,就要按顺序逐一插入队伍了,直接根据当前people[i]的k值,将people[i]插入对应的k位置即可,这样可以保证people[i]的前面不比他矮的人数就是k。        

class Solution {public int[][] reconstructQueue(int[][] people) {Arrays.sort(people, new Comparator<int[]>() {public int compare(int[] o1, int[] o2) {if(o1[0] != o2[0]){return o2[0] - o1[0];  //身高降序排列} else {return o1[1] - o2[1];  //前方需要插入人数升序排列}}});List<int[]> result = new ArrayList<>();for (int i = 0; i < people.length; i++) {result.add(people[i][1], people[i]);}return result.toArray(new int[people.length][]);}
}

看完代码随想录之后的想法 

        一开始写排序算法重写了很多次,一直没有想清楚插入排序之前的数组应该如何优先排序,所以怎么都写不对。偷看了一下随想录的排序方法,才写对compare函数。

        此外,虽然list类型可以用来进行插入排序,但其底层实现毕竟是数组,效率不高,换成链表会更好。

class Solution {public int[][] reconstructQueue(int[][] people) {// 身高从大到小排(身高相同k小的站前面)Arrays.sort(people, (a, b) -> {if (a[0] == b[0]) return a[1] - b[1];   // a - b 是升序排列,故在a[0] == b[0]的狀況下,會根據k值升序排列return b[0] - a[0];   //b - a 是降序排列,在a[0] != b[0],的狀況會根據h值降序排列});LinkedList<int[]> que = new LinkedList<>();for (int[] p : people) {que.add(p[1],p);   //Linkedlist.add(index, value),會將value插入到指定index裡。}return que.toArray(new int[people.length][]);}

遇到的困难

        对于多维度的贪心,还是要一个一个维度想清楚具体的贪心方法,再结合起来,不然很容易想错。

452. 用最少数量的箭引爆气球

题目链接:​​​​​​​452. 用最少数量的箭引爆气球

代码随想录题解:​​​​​​​452. 用最少数量的箭引爆气球

视频讲解:贪心算法,判断重叠区间问题 | LeetCode:452.用最少数量的箭引爆气球_哔哩哔哩_bilibili

解题思路:

        题目已经提醒了,这道题本质就是求相交区间的问题。如果多个区间同时相交,就只需要一根箭。

        因此,可以先对区间进行排序,以左边界为第一关键字,右边界为第二关键字,得到排序后的区间。然后用arrowPoint记录当前相交区间的范围,初始化为第一个区间的大小,此时需要的箭数量为1。然后遍历所有的区间,如果当前区间的左边界大于arrowPoint右边界,说明区间不相交,所需箭的数量加一,arrowPoint更新为当前区间范围;否则说明当前区间与arrowPoint有相交,此时更新arrowPoint的右边界为二者右边界的更小值即可。

class Solution {public int findMinArrowShots(int[][] points) {if (points.length <= 1) return points.length;Arrays.sort(points, new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {if (o1[0] == o2[0])return Integer.compare(o1[1], o2[1]);return Integer.compare(o1[0], o2[0]);}});int count = 1;int[] arrowPoint = points[0];for (int i = 1; i < points.length; i++) {if (points[i][0] > arrowPoint[1]) {count++;arrowPoint = points[i];} else {arrowPoint[0] = points[i][0];arrowPoint[1] = Math.min(arrowPoint[1], points[i][1]);}}return count;}
}

看完代码随想录之后的想法 

        有一些可以优化的地方:区间排序其实只需要针对左边界,右边界可以不需要;arrowPoint也可以直接用当前point代替,减少一点变量的使用。不过这样涉及到修改point数组了,个人不是特别喜欢。

/*** 时间复杂度 : O(NlogN)  排序需要 O(NlogN) 的复杂度* 空间复杂度 : O(logN) java所使用的内置函数用的是快速排序需要 logN 的空间*/
class Solution {public int findMinArrowShots(int[][] points) {// 根据气球直径的开始坐标从小到大排序// 使用Integer内置比较方法,不会溢出Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));int count = 1;  // points 不为空至少需要一支箭for (int i = 1; i < points.length; i++) {if (points[i][0] > points[i - 1][1]) {  // 气球i和气球i-1不挨着,注意这里不是>=count++; // 需要一支箭} else {  // 气球i和气球i-1挨着points[i][1] = Math.min(points[i][1], points[i - 1][1]); // 更新重叠气球最小右边界}}return count;}
}

遇到的困难

        一开始重写compare方法的时候,直接return o1[0]-o2[0]了,导致有一个测试用例的结果不对,因为相减后结果超过了int的上限,溢出了,后面才改写为Integer.compare,需要吸取一下教训。

今日收获

        又学了很多贪心的方法。感觉贪心的题目与现实比较接近,最好的办法是先实际模拟一遍做法,再看是否有优化空间。

这篇关于代码随想录算法训练营第三十五天| 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/888896

相关文章

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

Java实现状态模式的示例代码

《Java实现状态模式的示例代码》状态模式是一种行为型设计模式,允许对象根据其内部状态改变行为,本文主要介绍了Java实现状态模式的示例代码,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来... 目录一、简介1、定义2、状态模式的结构二、Java实现案例1、电灯开关状态案例2、番茄工作法状态案例

nginx-rtmp-module模块实现视频点播的示例代码

《nginx-rtmp-module模块实现视频点播的示例代码》本文主要介绍了nginx-rtmp-module模块实现视频点播,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录预置条件Nginx点播基本配置点播远程文件指定多个播放位置参考预置条件配置点播服务器 192.

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...