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

news2024/11/25 4:52:50

860.柠檬水找零 

这道题自己不看答案能自己做出来

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        if(bills[0]==10 || bills[0]==20) return false;
        int fivenum = 0;
        int tennum = 0;
        int tewentynum = 0;
        for(int i = 0;i<bills.size();i++){
            if(bills[i] == 5){
                fivenum++;
            }else if(bills[i] == 10){
                if(fivenum>0){
                    fivenum--;
                    tennum++;
                }else{
                    return false;
                }
            }else if(bills[i]==20){
                if(tennum>0&&fivenum>0){
                    fivenum--;
                    tennum--;
                    tewentynum++;
                }else if(tennum==0&&fivenum>=3){
                    fivenum = fivenum - 3;
                    tewentynum++;
                }else {
                    return false;
                }
            }
        }
        return true;
    }
};

406.根据身高重建队列

注意自己实现排序函数

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

其实如果大家认真做了135. 分发糖果 (opens new window),就会发现和此题有点点的像。

在135. 分发糖果 (opens new window)我就强调过一次,遇到两个维度权衡的时候,一定要先确定一个维度,再确定另一个维度。

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

对于本题相信大家困惑的点是先确定k还是先确定h呢,也就是究竟先按h排序呢,还是先按照k排序呢?

如果按照k来从小到大排序,排完之后,会发现k的排列并不符合条件,身高也不符合条件,两个维度哪一个都没确定下来。

那么按照身高h来排序呢,身高一定是从大到小排(身高相同的话则k小的站前面),让高个子在前面。

此时我们可以确定一个维度了,就是身高,前面的节点一定都比本节点高!

那么只需要按照k为下标重新插入队列就可以了,为什么呢?

以图中{5,2} 为例:

按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。

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

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

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

局部最优可推出全局最优,找不出反例,那就试试贪心。

一些同学可能也会疑惑,你怎么知道局部最优就可以推出全局最优呢? 有数学证明么?

在贪心系列开篇词关于贪心算法,你该了解这些! (opens new window)中,我已经讲过了这个问题了。

刷题或者面试的时候,手动模拟一下感觉可以局部最优推出整体最优,而且想不到反例,那么就试一试贪心,至于严格的数学证明,就不在讨论范围内了。

如果没有读过关于贪心算法,你该了解这些! (opens new window)的同学建议读一下,相信对贪心就有初步的了解了。

回归本题,整个插入过程如下:

排序完的people: [[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]]

插入的过程:

  • 插入[7,0]:[[7,0]]
  • 插入[7,1]:[[7,0],[7,1]]
  • 插入[6,1]:[[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]]
  • 插入[4,4]:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]

此时就按照题目的要求完成了重新排列。

 

class Solution {
public:
    static bool cmd(const vector<int>& v1,const vector<int>& v2){
            if(v1[0]==v2[0]){
                return v1[1]<v2[1];
            }
            return v1[0]>v2[0];
        }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        
        sort(people.begin(),people.end(),cmd);
        vector<vector<int>> result;
        for(int i = 0;i<people.size();i++){
            int index = people[i][1];
            result.insert(result.begin()+index,people[i]);
        }
        return result;
    }
};

将vector容器换成list链表更好,因为每次insert需要的开销都很大。

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

如何使用最少的弓箭呢?

直觉上来看,貌似只射重叠最多的气球,用的弓箭一定最少,那么有没有当前重叠了三个气球,我射两个,留下一个和后面的一起射这样弓箭用的更少的情况呢?

尝试一下举反例,发现没有这种情况。

那么就试一试贪心吧!局部最优:当气球出现重叠,一起射,所用弓箭最少。全局最优:把所有气球射爆所用弓箭最少。

算法确定下来了,那么如何模拟气球射爆的过程呢?是在数组中移除元素还是做标记呢?

如果真实的模拟射气球的过程,应该射一个,气球数组就remove一个元素,这样最直观,毕竟气球被射了。

但仔细思考一下就发现:如果把气球排序之后,从前到后遍历气球,被射过的气球仅仅跳过就行了,没有必要让气球数组remove气球,只要记录一下箭的数量就可以了。

以上为思考过程,已经确定下来使用贪心了,那么开始解题。

为了让气球尽可能的重叠,需要对数组进行排序

那么按照气球起始位置排序,还是按照气球终止位置排序呢?

其实都可以!只不过对应的遍历顺序不同,我就按照气球的起始位置排序了。

既然按照起始位置排序,那么就从前向后遍历气球数组,靠左尽可能让气球重复。

从前向后遍历遇到重叠的气球了怎么办?

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

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

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

class Solution {
public:
    static bool cmd(const vector<int>& v1,const vector<int> &v2){
        return v1[0]<v2[0];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        if(points.size()==0) return 0;
        sort(points.begin(),points.end(),cmd);
        int result = 1;
        for(int i = 1;i<points.size();i++){
            if(points[i][0]>points[i-1][1]){
                result++;
            }else{
                points[i][1] = min(points[i][1],points[i-1][1]);
            }
        }
        return result;
    }
};

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

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

相关文章

Hyper-V 虚拟机安装Ubuntu

Hyper-V 是win自带的虚拟机软件&#xff0c; 免费 进入控制面板&#xff0c;启用功能 勾选Hyper-V 然后重启电脑 打开 Hyper-v快速创建 此处可能需要 science surf network&#xff0c;否则创建虚拟机按钮为灰色 选择合适的版本&#xff0c;点击右下角的创建虚拟机进行安装&a…

【云时代数据利器】奥威BI SaaS版:一键链接云星空,套用百张报表

SaaS模式可以有效加快部署、提高效率、降低成本、提高灵活性&#xff0c;因此广受欢迎。随着市场的需求以及SaaS模式的广为人知&#xff0c;SaaS BI正逐渐成为BI的未来趋势之一&#xff0c;正逐渐成为云时代数据分析利器。奥威BI SaaS版和金蝶云星空标准方案强强联合&#xff0…

C++学习 结构体

目录 结构体 结构体定义和使用 结构体数组 结构体指针 结构体嵌套结构体 结构体做函数的参数 结构体中const使用场景 结构体 结构体定义和使用 定义&#xff1a; 结构体属于用户自定义的数据类型&#xff0c;允许用户存储不同的数据类型。 语法&#xff1a; struct 结构体…

day4 qtqtqtc++

cppcpp ui代码 <?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Widget</class><widget class"QWidget" name"Widget"><property name"geometry"><rec…

Linux--获取与杀死当前进程PID

获取当前进程的代码&#xff1a; #include <sys/types.h>pid_t idgetpid();//获取的是自己的进程PID 杀死当前进程的指令&#xff1a; kill -9 进程的PID 我要是kill -9 16865(-bash进程)&#xff0c;你会发现无论你输入clear、ls、还是vim...指令&#xff0c;都无…

云深处绝影四足机器人协议学习解析

绝影四足机器人通信协议学习解析 本学习文档介绍了云深处 绝影X20 四足机器人的通信协议&#xff0c;并对相关的通信机制和命令格式进行了简单的解析。该协议在机器人系统和上位机&#xff08;例如外部板卡或系统&#xff09;之间进行TCP通信时使用。 1. 协议端口号 在此协议…

定义一个派生自D1的D2类,并且在D2中覆盖pvf();建立一个D2类的对象并且调用f()、vf()、pvf()

运行代码&#xff1a; //定义一个派生自D1的D2类&#xff0c;并且在D2中覆盖pvf() //建立一个D2类的对象并且调用f()、vf()、pvf() #include"std_lib_facilities.h" //---------------------------------------------------------------------- //定义B1类。 class …

配置通过域名访问网站(NETBASE第七课)

1 DNS服务器 域名系统_百度百科 域名和与之相对应的IP地址转换的服务器 DNS&#xff08;Domain Name Server&#xff0c;域名服务器&#xff09;是进行域名(domain name)和与之相对应的IP地址 (IP address)转换的服务器。DNS中保存了一张域名(domain name)和与之相对应的IP地…

通过GitHub Desktop,将本地项目上传到gitee上

介绍 这里主要介绍&#xff0c;通过 gitHub Desktop 软件&#xff0c;将本地的项目&#xff0c;上传到 gitee的仓库里&#xff08;这里仓库为新建的仓库&#xff0c;什么东西都没有&#xff09;。 这里主要介绍&#xff0c;仓库的新建方式&#xff0c;及本地代码上传到远端的操…

Unity 实现一个揭面膜效果

源码 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;

【Django】列表页面的搜索功能

目的 页面列表增加多字段搜索显示查询结果 方案 分页显示搜索结果 效果 实现 列表页面 # list.html <div class"pull-left" style"margin-bottom: 10px"><form action"{% url api-search %}" method"get"><div …

ModaHub魔搭社区:开源向量数据库的Milvus怎么读?

Milvus是一个中文词语,意为“Milvus navigate,为智慧找方向,为价值做链接,为创作者做伙伴”。在读这个词语时,可以按照以下方式发音: 首先,我们需要将Milvus这个词语分解成多个音节。根据汉语拼音的规则,可以将其分解为“mi”、“lu”、“su”。 接下来,我们需要根…

Java阶段五Day03

Java阶段五Day03 文章目录 Java阶段五Day03回顾git命令Git远程仓库远程仓库概念远程仓库分支操作分支管理策略 回顾git命令 本地版本控制 git initgit addgit commitgit loggit statusgit taggit refloggit reset 分支管理 git branchgit branch b1git checkout b1git merg…

C#核心知识回顾——13.多线程、预处理器指令

1.多线程 了解线程前先了解进程 进程&#xff08;Process&#xff09;是计算机中的程序关于某数据集合上的一次运行活动 是系统进行资源分配和调度的基本单位&#xff0c;是操作系统结构的基础 说人话&#xff1a;打开个应用程序就是在慢作系统上开启了一个进程 进程之间可以相…

【Vscode】解决 An SSH installation couldn‘t be found

【Vscode】解决 An SSH installation couldn‘t be found 背景描述&#xff1a;在vscode中使用ssh进行连接到时候&#xff0c;已经安装了ssh romote的plugin插件&#xff0c;但是在输入了ssh连接命令之后&#xff0c;仍然出现报错&#xff1a;an ssh installation could not be…

vue3+mapboxgl鼠标浮动显示cgcs2000

一、需求 鼠标在地图中浮动展示地图的经纬度&#xff0c;cgcs2000 xy 还有显示带号 二、实现效果 展示经度&#xff0c;纬度&#xff0c;x值&#xff0c;y值显示的是带号和y值 三、思路 3.1、mapbox获取经纬度方法 初始化地图后.on方法中有个mousemove方法 mapboxUtil._m…

leetcode:递增的三元子序列

递增的三元子序列 题解部分转自leetcode:Xzz medium 给你一个整数数组 nums &#xff0c;判断这个数组中是否存在长度为 3 的递增子序列。 如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k &#xff0c;使得 nums[i] < nums[j] < nums[k] &#xff0c;返回…

专享策略06 | 盘口策略CTP实盘版

量化策略开发&#xff0c;高质量社群&#xff0c;交易思路分享等相关内容 『正文』 ˇ 大家好&#xff0c;我们在6月29日发布了盘口策略| 回测版&#xff0c;今天我们做好了CTP的实盘版本供俱乐部会员使用和玩耍&#xff0c;今天主要说明一下如何使用CTP实盘版本。 先回顾一…

线上展厅设计方案,个性化自主打造720漫游展厅

导语&#xff1a; 随着科技的不断进步&#xff0c;线上展厅作为一种新型的展示方式&#xff0c;在现代社会得到了广泛的应用。线上展厅通过虚拟技术和创新设计&#xff0c;突破了时间和地域的限制&#xff0c;为企业和观众带来了全新的展览体验。本文将重点探讨线上展厅的优势和…

【工具使用】STM32CubeMX-单ADC模式规则通道配置

一、概述 无论是新手还是大佬&#xff0c;基于STM32单片机的开发&#xff0c;使用STM32CubeMX都是可以极大提升开发效率的&#xff0c;并且其界面化的开发&#xff0c;也大大降低了新手对STM32单片机的开发门槛。     本文主要讲述STM32芯片的ADC的配置及其相关知识。 二、…