LeetCode刷题day19——贪心

LeetCode刷题day19——贪心

    • 55. 跳跃游戏
      • 分析:
    • 45. 跳跃游戏Ⅱ
      • 分析:
    • 452. 用最少数量的箭引爆气球
      • 分析:
            • **总结**

55. 跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false

示例 1:

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

  • 1 <= nums.length <= 104
  • 0 <= nums[i] <= 105

分析:

怎么跳不重要,我站在i这里,nums[i]=3,其实我跳1,2,3都不重要,重要的是我究竟能覆盖多远的范围。想明白了这个,就不难了,秒掉。

class Solution {
public:bool canJump(vector<int>& nums) {int Max = 0;int i = 0;int len = nums.size();while (i != len) {if (i <= Max) {//我正处于覆盖的范围里Max = max(Max, nums[i] + i);//范围取大i++;} else//不能走,失败break;}if (Max >= len - 1)//下标大于等于最后一个位置return true;elsereturn false;}
};

45. 跳跃游戏Ⅱ

给定一个长度为 n0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

示例 1:

输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

输入: nums = [2,3,0,1,4]
输出: 2

提示:

  • 1 <= nums.length <= 104
  • 0 <= nums[i] <= 1000
  • 题目保证可以到达 nums[n-1]

分析:

刚开始拿到,确实有点小难(可能是我太菜),至少比上一题难一些。但是想来想去,想到策略之后还是很好实现的,一开始只能过部分样例,然后样例能通过的越来越多,最后全对,嘿嘿,好开心。然后还规整了代码,这次很值得鼓励,我都没参考别人的代码,自己写的哈哈,上一题也是自己打的哈哈。好嗨森!

关键:贪心思想,每步尽可能多走。每次都要去计算下一步能走多远,当然是选择能走最远的那一步!

class Solution {
public:int jump(vector<int>& nums) {//贪心策略:一步尽可能多走,早点覆盖到终点范围int curReach_Max = 0;int nextReach_Max = 0;int next = 0;//下一步跳到哪里int i = 0;int jump = 1;int len = nums.size();if (1 == len )//输入nums=[0],i==len-1其实起点就是终点了return 0;while (i < len) {curReach_Max = nums[i] + i;//现在能覆盖的范围if(curReach_Max>=len-1)//如果直接能到,就successreturn jump;for (int j = i + 1; j <= curReach_Max&&j<len; j++) {//在现在能覆盖的范围中,查找下一步可能到达的最大范围,记录下标;也就是下一步要跳到的地方if (nums[j] + j > nextReach_Max) {nextReach_Max = nums[j] + j;next = j;}}//明确下一步跳到哪里了jump++;i = next;//do jump}return  jump;}
};

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

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

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

给你一个数组 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

分析:

我写出来了,是的!值得庆祝。

class Solution {
public:int findMinArrowShots(vector<vector<int>>& points) {//先对数组按x0排序,找重叠区间,其中的右边界最小值必须得放一支箭sort(points.begin(), points.end(),[](vector<int>& a, vector<int>& b) { return a[0] < b[0]; });vector<bool> visited(points.size(), false);//记录是否已经被处理int line = INT_MAX;int count = 0;//放箭数for (int i = 0; i < points.size(); i++) {if (visited[i])//被处理就跳过continue;if (i > 0 && !visited[i - 1])//不是第一个,并且前一个没被处理,加入最小右边界的比较line = min(points[i][1], line);else//都被处理光了,新开一条线line = points[i][1];int j = i;while (j < points.size() && points[j][0] <= line) {//重叠区间出现了,坚持不懈寻找最小右边界line = min(points[j][1], line);visited[j] = true;j++;}count++;}return count;}
};

但是gpt说给我优化,优化得关键部位只剩四行代码了!那我辛辛苦苦写这么多,我算什么啊,呜呜~

class Solution {
public:int findMinArrowShots(vector<vector<int>>& points) {sort(points.begin(), points.end(), [](vector<int>& a, vector<int>& b) {return a[1] < b[1];  // 按右边界排序});int count = 0;long long arrow = (long long)INT_MIN - 1; // 使用更小的初始值避免冲突for (const auto& point : points) {if (point[0] > arrow) {  // 当前区间起点在箭的范围之外,需要新箭arrow = point[1];count++;}}return count;}
};

而且,按照右边界排序更好,按右边界排序的优点

  1. 逻辑简单: 右边界排序后,遍历时每个区间的右边界是当前最优位置,只需判断左边界即可。
  2. 贪心策略自然: 每次在当前右边界处放箭,是覆盖尽可能多区间的最优选择。
  3. 避免更新右边界的额外操作: 按右边界排序后,右边界天然有序,不需要手动调整。

总结
  • 右边界排序简化了区间合并的逻辑,是经典的贪心策略。
  • 左边界排序虽然也可行,但需要更复杂的逻辑来追踪右边界,因此一般不采用。

总之,我已经很贪心了,他好像更贪心哈哈~

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

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

相关文章

Python爬虫之selenium库驱动浏览器

目录 一、简介 二、使用selenium库前的准备 1、了解selenium库驱动浏览器的原理 &#xff08;1&#xff09;、WebDriver 协议 &#xff08;2&#xff09;、 浏览器驱动&#xff08;Browser Driver&#xff09; &#xff08;3&#xff09;、 Selenium 客户端库 &#xff0…

Vite+Vue3项目实战:组件化开发与通信指南

一、典型的ViteVue3项目结构 续上文成功创建Vue3项目的脚手架&#xff0c;通过visual Studio Code软件打开刚刚创建的文件夹&#xff0c;将会看到这样一个项目结构。 使用Vite构建Vue3项目时&#xff0c;项目结构通常遵循一定的组织规则&#xff0c;以保持代码的清晰和可维护性…

汽车免拆案例 | 2007款宝马650i车发动机偶尔无法起动

故障现象 一辆2007款宝马650i车&#xff0c;搭载N62B48B发动机&#xff0c;累计行驶里程约为26万km。车主反映&#xff0c;发动机偶尔无法起动&#xff0c;故障频率较低&#xff0c;十几天出现1 次&#xff0c;且故障出现时起动机不工作。 故障诊断  接车后试车&#xff0c;…

团队管理中如何做好目标管理

团队管理中的目标管理是确保团队高效运行的核心要素之一。 在目标管理中&#xff0c;清晰的目标设定、合理的资源分配、实时的跟踪与反馈机制是成功的关键。首先&#xff0c;设定SMART目标&#xff08;具体、可衡量、可达成、相关性强、时间限定&#xff09;能够有效聚焦团队的…

【力扣热题100】—— Day4.反转链表

你不会永远顺遂&#xff0c;更不会一直年轻&#xff0c;你太安静了&#xff0c;是时候出发了 —— 24.12.2 206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&…

【AWS re:Invent 2024】一文了解EKS新功能:Amazon EKS Auto Mode

文章目录 一、为什么要使用 Amazon EKS Auto Mode&#xff1f;二、Amazon EKS自动模式特性2.1 持续优化计算成本2.2 迁移集群操作2.3 EKS 自动模式的高级功能 三、EKS Auto 集群快速创建集群配置四、查看来自 API 服务器的指标五、EKS 相关角色权限设置六、参考链接 一、为什么…

记事本建java及java命名规范

1.桌面开发&#xff1a;c# 2. 记事本建java&#xff1a; 以class的名称(类名)为名&#xff0c;名称.java 编译jdk&#xff1a;javac 名称.java 调动运行jre : java 名称 查看名称.java里面的内容&#xff1a;cat 名称.java java 的命名规范 大驼峰&#xff08;每个单词首…

过程管理系统(源码+文档+部署+讲解)

本文将深入解析“过程管理系统”的项目&#xff0c;探究其架构、功能以及技术栈&#xff0c;并分享获取完整源码的途径。 系统概述 过程管理系统是一款专为工业设计的综合管理平台&#xff0c;旨在通过集成各种管理流程和功能模块来提高管理效率和安全性。系统提供了从登录系…

期权懂|个股期权交割操作流程是什么样的?

期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 个股期权交割操作流程是什么样的&#xff1f; 一、行权申报&#xff1a; 期权买方在行权日通过其经纪商提交行权指令&#xff0c;表明其决定行使期权权利。 二、行权匹配&#xf…

智能仓储:入库业务流程介绍

01 入库流程 入库业务流程&#xff0c;常见过程是这样的&#xff1a; 创建PO单 > 创建到货清单 > 核对货物 > 入库质检 > 货物贴标签 > 上架 > 库存同步 1、创建PO单 po单指的是的采购订单&#xff0c;比如采购了一车货品&#xff0c;这车的货品可以理解…

MySQL并发控制(一):幻读

假设有如下表结构&#xff1a; CREATE TABLE t(id int(11) NOT NULL,c int(11) DEFAULT NULL,d int(11) DEFAULT NULL,PRIMARY KEY (id),KEY c (c) ) ENGINEInnoDB;insert into t values(0,0,0),(5,5,5),(10,10,10),(15,15,15),(20,20,20),(25,25,25); 问&#xff1a;如果执行…

Ubuntu22.04中mysql8 rpm安装

1、安装依赖 sudo apt update sudo apt -y dist-upgrade sudo apt -y install vim net-tools wget gcc make cmake lrzsz sudo apt -y install libmecab2 libjson-perl 2、下载rpm文件 https://dev.mysql.com/downloads/mysql/ https://cdn.mysql.com//Downloads/MySQL-8.0/m…

Intel 性能分析“全家桶” For HPC(一)

本系列是对于HPC应用性能分析涉及的主要方法论及Intel主流工具分享。理解这些方法论将有助于对性能分析结果的理解。同时方法论也可以推广到其他的硬件平台的分析上。除此之外后面也将介绍如何用Vtune, Advisor以及ITAC进行性能分析&#xff0c;以及在性能分析过程中这三种性能…

Qwen1.8B大模型微调流程

提示&#xff1a;本篇笔记是在微调大模型为法律相关模型的教程下记录的&#xff0c;参考的讲解视频在B站上&#xff0c;一搜微调大模型为法律大模型就有很多视频。 文章目录 1. 数据集1.1 数据下载1.2 数据格式转换 2. 模型训练2.1 安装依赖2.2 模型训练 3. 模型推理3.1 LoRA模…

第十六章 使用 iSCSI 服务部署网络存储

1. iSCSI 技术介绍 硬盘是计算机硬件设备中重要的组成部分之一&#xff0c;硬盘存储设备读写速度的快慢也会对服务器的整体性能造成影响。硬盘存储结构、RAID 磁盘阵列技术以及LVM 技术等都是用于存储设备的技术&#xff0c;尽管这些技术有软件层面和硬件层面之分&#xff0c…

【js面试题】JavaScript 中箭头函数与普通函数的深度剖析

在 JavaScript 编程的世界里&#xff0c;函数是极为重要的组成部分。而随着 ES6 的出现&#xff0c;箭头函数成为了 JavaScript 函数家族中的新成员。它与传统的普通函数有着诸多的不同之处&#xff0c;这些差异深刻地影响着我们编写代码的方式以及代码的执行逻辑。本文将对 Ja…

【漫话机器学习系列】Adaboost算法

Adaboost&#xff08;Adaptive Boosting&#xff09;是一种经典的集成学习方法&#xff0c;主要思想是通过将多个弱学习器&#xff08;通常是简单模型&#xff0c;如决策树桩&#xff09;加权组合&#xff0c;来提升整体模型的预测能力。Adaboost 是一种自适应的学习方法&#…

SQL靶场第四关

sql靶场第四关攻略 输入?id1页面正常 输入?id1发现页面也正常 输入?id1"&#xff0c;页面异常&#xff0c;说明存在sql报错注入 在输入?id1" --页面还是报错 1.判断闭合点 我们需要找到闭合点&#xff0c;尝试在双引号后面加个) 输入?id1") --我们发现…

Trunk链路操作题

Trunk链路操作题 论证&#xff1a;

Alogrithm:三色棋

1. 说明 三色旗的问题最早由 E.W.Diikstra 所提出&#xff0c;他所使用的用语为 Dutch Nation Flag&#xff08;Dijkstra 为荷兰人&#xff09;&#xff0c;而多数的作者则使用 Three-Color Flag 来称之。 假设有一条绳子&#xff0c;上面有红、白、蓝三种颜色的旗子&#xff0…