代码随想录第35天| 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

860.柠檬水找零

860. 柠檬水找零 - 力扣(LeetCode)

代码随想录 (programmercarl.com)

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

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

注意,一开始你手头没有任何零钱。

给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

示例 1:

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

示例 2:

输入:bills = [5,5,10,10,20]
输出:false
解释:
前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。

提示:

  • 1 <= bills.length <= 105
  • bills[i] 不是 5 就是 10 或是 20 

bills[i]不是5就是10或者20,可以把所有情况都列出来:
1、收取5,不用找零

2、收取10,必须找零5,也就是说在10之前必须有至少一个5

3、收取20,必须找零15,也就是说在20之前必须至少有一个10和一个5;或者有3个5

那怎么应用贪心算法呢?贪心在哪儿?

收取20的时候,可以选择找零10,也可以选择找零5,这时候优先选择找零10,手上多留一些5,预防后面再收到10。这就是贪心策略。

class Solution{
    int five = 0;
    int ten = 0;
    for(int i = 0, i < bills.length, i++){
        if(bills[i] == 5){
            five++;
        }else if(bills[i] ==10){
            five-=1;
            ten++;
        }else if(bills[i] ==20){
            if(ten > 0){
                ten--;
                five--;
            }else{
                five-=3;
            }
        }
        if(five < 0 || ten < 0) return false;
    }
    return true;
}
}

 406.根据身高重建队列 

406. 根据身高重建队列 - 力扣(LeetCode)

代码随想录 (programmercarl.com)

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

假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。

示例 1:

输入: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]]
解释:
编号为 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]] 是重新构造后的队列。

示例 2:

输入:people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]]
输出:[[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]

提示:

  • 1 <= people.length <= 2000
  • 0 <= hi <= 106
  • 0 <= ki < people.length
  • 题目数据确保队列可以被重建

本题有2个维度h和k,要分开考虑,不然就会顾此失彼。

那2个维度先考虑哪一个呢?先考虑k试试:

 输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]

按照k从小到大排序:[5,0] [7,0] [6,1] [7,1] [5,2] [4,4]

应该输出:输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]

对比我们得到的序列和应该输出的序列可以发现,我们得到的序列仍然很乱,所以我们再试试按照h排序:

 输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]

按照h从大到小排序,h相同时k从小到大:[7,0] [7,1] [6,1] [5,0] [5,2] [4,4]

应该输出:输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]

此时把[6,1]的位置不太符合,把[6,1]移到下标为1的位置(也就是第2个位置):

 [7,0] [6,1] [7,1] [5,0] [5,2] [4,4]

继续向后遍历,[5,0]的位置不太符合,把[5,0]移到下标为0的位置(也就是第1个位置):

  [5,0]  [7,0] [6,1] [7,1] [5,2] [4,4]

 继续向后遍历,[5,2]的位置不太符合,把[5,2]移到下标为2的位置(也就是第3个位置):

  [5,0]  [7,0] [5,2] [6,1] [7,1] [4,4]

继续向后遍历,[4,4]的位置不太符合,把[4,4]移到下标为4的位置(也就是第5个位置):


  [5,0]  [7,0] [5,2] [6,1] [4,4] [7,1]

以上队列刚好满足题目要求!!! 那移动的位置有什么规律吗?观察背景为黄色的数字可以发现,应该移动的人的k刚好是需要移动到的位置的下标

所以在按照身高从大到小排序后:

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

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

综合代码:

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][]);
    }
}

以上代码中:

应用了lambda表达式,lambda表达式:

 以上代码运用了增强for循环:

增强for循环:增强for循环 (也称for each循环) 是迭代器遍历方法的一个“简化版”,是JDK1.5以后出来的一个高级for循环,专门用来遍历数组集合

增强for循环的使用:

for(ElementType element: arrayName) 
{ //集合或数组的数据类型 变量名:集合名/数组名
	System.out.println(变量名);
};

上述for循环可被读为:
for each element in arrayName do {…}

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

452. 用最少数量的箭引爆气球 - 力扣(LeetCode)

代码随想录 (programmercarl.com)

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

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstartxend, 且满足  xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。

给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 

示例 1:

输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]。

示例 2:

输入:points = [[1,2],[3,4],[5,6],[7,8]]
输出:4
解释:每个气球需要射出一支箭,总共需要4支箭。

示例 3:

输入:points = [[1,2],[2,3],[3,4],[4,5]]
输出:2
解释:气球可以用2支箭来爆破:
- 在x = 2处发射箭,击破气球[1,2]和[2,3]。
- 在x = 4处射出箭,击破气球[3,4]和[4,5]。

提示:

  • 1 <= points.length <= 105
  • points[i].length == 2
  • -231 <= xstart < xend <= 231 - 1

将气球按照左边界从小到大的位置排序,2个边界有重合就用一只箭一起射。

局部最优:当气球出现重叠,一起射,所用弓箭最少。全局最优:把所有气球射爆所用弓箭最少。

如果气球重叠了,重叠气球中右边边界的最小值 之前的区间一定需要一个弓箭

以题目示例: [[10,16],[2,8],[1,6],[7,12]]为例,如图:(方便起见,已经排序)

可以看出首先第一组重叠气球,一定是需要一个箭,气球3,的左边界大于了 第一组重叠气球的最小右边界,所以再需要一支箭来射气球3了。

综合代码:

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;
    }
}

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

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

相关文章

如何在 iOS 项目中集成 MiniApp SDK,快速构建智能小程序?

本文介绍如何在 iOS 项目中&#xff0c;集成 MiniApp SDK&#xff0c;使之能够构建智能生活小程序&#xff0c;运行在你的 IoT App 上。 准备工作 在集成 MiniApp SDK 之前&#xff0c;您需要在 涂鸦 IoT 开发平台 上&#xff1a; 注册开发者账号、创建产品、创建功能点等。…

【静态分析】静态分析笔记02 - Intermediate Representation

参考&#xff1a; [南京大学]-[软件分析]课程学习笔记(二)-IR_ast和ir的区别-CSDN博客 ------------------------------------------------------------------------------------------------------------ 1. compilers and static analyzers compiler 是将 Source Code 转…

实时云渲染视频流化Webgl引擎模型技术原理

数字孪生领域很多项目B/S架构下交付使用的是webgl方案&#xff0c;该方案有其自身的优势&#xff0c;降低了用户在使用数字孪生或者虚拟仿真模型时需要的高性能显卡。但其也有自身无法忽视的困境&#xff0c;比如一些数据量大的模型&#xff0c;需要验证依赖下载时的网络环境&a…

c语言驾驶员理论课程模拟考试与学习系统1300

定制魏&#xff1a;QTWZPW&#xff0c;获取更多源码等 目录 1问题描述 2功能要求 【选做要求】 【其他要求】 部分代码展示 效果展示 程序设计题4:驾驶员理论课程模拟考试与学习系统 1问题描述 要求编写一个程序&#xff0c;模拟驾驶员科目一的考试&#xff0c;要求具有良…

Android获取连接到手机热点上的设备信息

主题&#xff1a;在手机开启热点网络的情况下&#xff0c;想要获取是哪个设备已经连接上了当前开启的热点。 实现思路&#xff1a;Android通过读取 /proc/net/arp 文件可以得到连接当前热点的设备信息&#xff0c;包括Mac地址、IP地址等信息。 一. 方法逻辑&#xff1a; /*** …

Webots常用的执行器(Python版)

文章目录 1. RotationalMotor2. LinearMotor3. Brake4. Propeller5. Pen6. LED 1. RotationalMotor # -*- coding: utf-8 -*- """motor_controller controller."""from controller import Robot# 实例化机器人 robot Robot()# 获取基本仿真步长…

IDEA无法成功配置Tomcat的解决方法(IDEA版本问题)

在创建Servlet时&#xff0c;下载了Tomcat文件夹以及成功配置了环境变量之后&#xff0c;在IDEA中怎么都找不到Tomcat&#xff0c;尝试了网络中的各种方法&#xff0c;都不行&#xff0c;结果发现时IDEA版本的问题。因为我下的IDEA是社区版的&#xff0c;所以没有自带的Tomcat&…

Flutter开发之图片选择器

使用FLutter开发了一个图片选择的组件&#xff0c;功能如下&#xff1a; 1、支持设置最大可选图片的个数&#xff1b; 2、根据选择的图片个数自适应容器组件的高度&#xff1b; 3、可设置容器的最大高度&#xff1b; 4、支持点击放大和删除功能&#xff1b; 具体效果如下 …

Linux系统安装内网穿透实现固定公网地址访问本地MinIO服务

文章目录 前言1. 创建Buckets和Access Keys2. Linux 安装Cpolar3. 创建连接MinIO服务公网地址4. 远程调用MinIO服务小结5. 固定连接TCP公网地址6. 固定地址连接测试 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&am…

【计算机考研】408算法大题怎么练?

先说结论&#xff1a;基础阶段学好各个数据结构与&#xff0c;重点是数组、链表、树、图。然后强化阶段突破算法提 在基础阶段&#xff0c;并不需要过于专门地练习算法。相反&#xff0c;基础阶段的重点应该放在对各种数据结构原理的深入理解上。在我个人的经验中&#xff0c;…

计算机考研择校|408还是自命题,哪个上岸难度大?

我一般是建议选择408&#xff0c;但是现在考408的同学太多了 所以408的竞争压力会比较大&#xff0c;加上复习难度大&#xff0c;复习过程中&#xff0c;心态很容易崩掉。 其实到底选自命题还是408&#xff0c;我觉得还是要看自己的目标。如果目标院校是自命题&#xff0c;那…

C语言的显式类型转换和隐式类型转换详细讲解

目录 一、类型转换 1、显式类型转换 2、隐式类型转换 二、算术转换 三、总结 每个编译器都会对表达式做两件事情&#xff0c;一是判断表达式中操作符的优先级和结合性&#xff0c;二是判断表达式中的操作数类型是否一致&#xff0c;如果不一致则需要进行类型转换。第一点在…

吴恩达机器学习实践实验室:决策树(Decision Trees)

在本练习中&#xff0c;您将从头开始实施决策树&#xff0c;并将其应用于蘑菇可食用还是有毒的分类任务。 文章目录 1-包2-问题陈述3-数据集3.1一个热编码数据集 4-决策树4.1计算熵4.2分割数据集4.3计算信息增益4.4获得最佳分割 5-构建树 1-包 首先&#xff0c;让我们运行下面…

【问题解决】ubuntu安装新版vscode报code-insiders相关错误

问题 目前 vscode官网 最新的包为 insiders_1.89.0-1712297812_amd64.deb &#xff0c;双击或者使用sudo dpkg -i code-insiders_1.89.0-1712297812_amd64.deb安装后报错&#xff0c;执行其他命令也报错。 安装环境&#xff1a;ubuntu18.04 dpkg: 处理软件包 code-insiders (…

代码随想录算法训练营第四十九天 | 121. 买卖股票的最佳时机、22. 买卖股票的最佳时机 II

代码随想录算法训练营第四十九天 | 121. 买卖股票的最佳时机、22. 买卖股票的最佳时机 II 121. 买卖股票的最佳时机题目解法 122. 买卖股票的最佳时机 II题目解法 感悟 121. 买卖股票的最佳时机 题目 解法 题解链接 没看题解想出来的&#xff1a;贪心 class Solution { pub…

归档模式下,物理删除数据文件的完全的恢复

归档模式下&#xff0c;物理删除数据文件的完全的恢复 1、实验环境 环境归档模式 SQL> archive log list Database log mode Archive Mode Automatic archival Enabled Archive destination /arch/archivelog Oldest online log seq…

用户态网络缓冲区的设计

一、网络缓冲区 在内核中也是有网络缓冲区的&#xff0c;比如使用 read 读取数据&#xff08;read 是一种系统调用&#xff0c;第一个参数为 fd&#xff09;&#xff0c;当陷入到内核态的时候&#xff0c;会通过 fd 指定 socket&#xff0c;socket 会找到对应的接收缓冲区。在…

抓住风口,快速上手RAG应用开发!

免责声明~ 任何文章不要过度深思&#xff01; 万事万物都经不起审视&#xff0c;因为世上没有同样的成长环境&#xff0c;也没有同样的认知水平&#xff0c;更「没有适用于所有人的解决方案」&#xff1b; 不要急着评判文章列出的观点&#xff0c;只需代入其中&#xff0c;适度…

37-代码测试(下):Go语言其他测试类型及IAM测试介绍

。 Go中的两类测试&#xff1a;单元测试和性能测试。 我就来介绍下Go 语言中的其他测试类型&#xff1a;示例测试、TestMain函数、Mock测试、Fake测试等&#xff0c; 示例测试 示例测试以Example开头&#xff0c;没有输入和返回参数&#xff0c;通常保存在example_test.go…

Go语言实现Redis分布式锁2

项目地址: https://github.com/liwook/Redislock 1.支持阻塞式等待获取锁 之前的是只尝试获取一次锁&#xff0c;要是获取失败就不再尝试了。现在修改为支持阻塞式等待获取锁。 添加LockOptions结构体 添加option.go文件。 在LockOptions中 isBlock表示是否是阻塞模式blo…