代码随想录 贪心算法-难度题目-区间问题

目录

55.跳跃游戏 

45.跳跃游戏||

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

435.无重叠区间 

763.划分字母区间

56.合并区间 


55.跳跃游戏 

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

运用覆盖位置来求解此题,每到一个位置都去尝试更新cover的值(如果走此步比之前的覆盖位置更大的情况下),如果覆盖位置覆盖到了最后一个数,,表示可以从起点跳到终点,返回true。遍历的结束位置是覆盖位置的最大点,如果此时cover还没有覆盖到最后一个数,说明不能从起点跳到终点。

class Solution {  public boolean canJump(int[] nums) {  // cover变量用来记录当前能够到达的最远位置  int cover = 0;  // 如果数组只有一个元素,则显然可以从该位置跳到终点(自己),返回true  if(nums.length == 1){  return true;  }  // 遍历数组,直到到达当前能够到达的最远位置cover  for(int i = 0; i <= cover; i++){  // 更新当前能够到达的最远位置,取当前位置能够到达的最远位置i + nums[i]和当前已知的最远位置cover中的较大值  cover = Math.max(cover, i + nums[i]);  // 如果当前能够到达的最远位置cover已经大于等于数组长度减一(即已经能够到达或超过数组的最后一个位置),  // 则表示可以从起点跳到终点,返回true  if(cover >= nums.length - 1){  return true;  }  }  // 如果遍历完数组后仍然没有找到能够到达终点的路径,则返回false  return false;  }  
}

45.跳跃游戏||

45. 跳跃游戏 II

中等

给定一个长度为 n 的 0 索引整数数组 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]

这里有nowcover和nextMaxCover两个变量,分别代表这一步能覆盖到的最远地点和下一步能覆盖到的最远地点 ,如果当前位置已经到了这一步能覆盖到的最远地点,跳出这一步,然后一步的nowcover换为在上一步中求得的nextMaxCover,继续向后遍历,如果nextMaxCover覆盖到了最后一个值,跳出这一步,到达最后一个值

class Solution {  public int jump(int[] nums) {  // 如果数组为空或者只有一个元素,则不需要跳跃,直接返回0  if(nums.length < 2 || nums == null){  return 0;  }  // 跳跃次数  int count = 0;  // 当前覆盖的最远位置  int nowCover = 0;  // 下一次跳跃能够覆盖的最远位置  int nextMaxCover = 0;  // 遍历当前覆盖位置中的每个位置  for(int i = 0; i <= nowCover; i++){  // 更新下一次跳跃能够覆盖的最远位置  nextMaxCover = Math.max(i + nums[i], nextMaxCover);  // 如果下一次跳跃能够直接到达数组末尾,则增加一次跳跃并跳出循环  if(nextMaxCover >= nums.length - 1){  count++;  break;  }  // 如果当前位置到达了当前能够覆盖的最远位置,说明需要进行一次跳跃  if(i == nowCover){  count++;  // 更新当前能够覆盖的最远位置为下一次跳跃能够覆盖的最远位置  nowCover = nextMaxCover;  }  }  // 返回跳跃次数  return count;  }  
}

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

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

中等

有一些球形气球贴在一堵用 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

思路:用最少的箭射最多的气球

从第二个气球开始,因为之前已经排过序,直接比较第二个气球的最左侧和第一个气球的最右侧,如果第二个气球的最左侧更大,说明两个气球没有交集,需要一支箭来射第二个气球。否则第二个气球和第一个气球有交集,可用同一根箭射,因为第二支箭的最左侧一定大于第一支箭的最左侧,选择第一个气球和第二个气球的最后侧中的最小值,赋值给第二个气球,得到第二个气球的范围即为第一二个气球的交集,之后的第三个气球如果和第二个气球现在的范围有交集,则说明前三个气球和前两个气球可以用同一支箭射,以此类推。

class Solution {  // 方法:找到射穿所有气球所需的最少箭数量  public int findMinArrowShots(int[][] points) {  // 根据每个气球的水平位置x进行排序,如果x相同,则保持原顺序  Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));  // 初始化箭的数量为1,因为至少需要一支箭来射穿第一个气球  int count = 1;  // 遍历所有气球(从第二个开始,因为第一个已经有一支箭了)  for(int i = 1; i < points.length; i++){  // 如果当前气球的水平位置最左侧大于前一个气球的水平位置最右侧if(points[i][0] > points[i-1][1]){  // 则需要增加一支箭来射穿当前气球  count++;  }else{  // 如果当前气球与前一个气球有重叠 // 则更新当前气球的垂直位置y为两个气球中更小的y值  // 这样做是为了保证在后续的迭代中,如果还有气球在这个垂直范围内,它们也可以被这支箭射穿  points[i][1] = Math.min(points[i][1],points[i - 1][1]);  }  }  // 返回所需的箭的数量  return count;  }  
}

435.无重叠区间 

435. 无重叠区间

中等

给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 

示例 1:

输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。

示例 2:

输入: intervals = [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。

示例 3:

输入: intervals = [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。

提示:

  • 1 <= intervals.length <= 105
  • intervals[i].length == 2
  • -5 * 104 <= starti < endi <= 5 * 104

思路: 首先对数组进行排序,从第二个开始遍历区间,如果区间和前一个区间有重合,这个时候我们要考虑删除该区间还是前一个区间,为了尽可能避免和后面的区间重合,我们留下结束位置更小的区间以求和下一个区间的开始位置保持距离。

class Solution {  // 方法:删除尽可能多的重叠区间,返回删除的数量  public int eraseOverlapIntervals(int[][] intervals) {  // 根据区间的起始位置进行排序,如果起始位置相同,则保持原顺序  Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));  // 初始化计数器,记录重叠区间的数量  int count = 0;  // 遍历所有区间(从第二个区间开始,因为第一个区间不需要比较)  for (int i = 1; i < intervals.length; i++) {  // 如果当前区间的起始位置小于前一个区间的结束位置,说明有重叠  if (intervals[i][0] < intervals[i - 1][1]) {  // 更新当前区间的结束位置为两个区间结束位置的较小值(这里相当于删除结束位置较大的区间) // 这样做是为了保留和下一个区间尽可能远的距离,避免和下一个区间重合intervals[i][1] = Math.min(intervals[i][1], intervals[i - 1][1]);  // 重叠区间数量加1  count++;  }  }  // 返回删除的重叠区间的数量  return count;  }  
}

763.划分字母区间

763. 划分字母区间

中等

提示

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。

返回一个表示每个字符串片段的长度的列表。

示例 1:

输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。 

示例 2:

输入:s = "eccbbbbdec"
输出:[10]

提示:

  • 1 <= s.length <= 500
  • s 仅由小写英文字母组成

先遍历一遍数组,得到每一个字母的最后出现位置。

再次遍历数组,记录当前区间中所有字母的最后出现位置的最大值,当索引等于该最大值位置时,说明当前区间中的所有字母在后边的数组中都不会出现,故得到一个区间,将长度存入结果集合中,并记录该区间的最后位置用来计算下一个区间的长度

class Solution {  // 方法:将字符串划分为若干个子串,使得每个子串中的所有字符都属于同一个字符集  public List<Integer> partitionLabels(String s) {  // 用于存储最终结果的列表,每个元素代表一个分区的长度  List<Integer> result = new ArrayList<>();  // 用于存储每个字符在字符串中最后出现的位置的数组  int[] charLastIndex = new int[27]; // 因为字符a到z共26个,再加上字符'a'的ASCII码值,所以数组大小为27  // 将字符串转换为字符数组,方便后续遍历  char[] sChar = s.toCharArray();  // 遍历字符串的每个字符,记录它们最后一次出现的位置  for (int i = 0; i < sChar.length; i++) {  charLastIndex[sChar[i] - 'a'] = i;  }  // 当前遍历到的字符在字符串中最后出现的位置  int nowLastIndex = 0;  // 上一个分区的结束位置//相当于第一个区间之前的区间在index为-1的时候结束  int lastEndIndex = -1;  // 遍历字符串的每个字符  for (int i = 0; i < sChar.length; i++) {  // 更新当前遍历到的字符集中所有字符在字符串中最后出现的位置  nowLastIndex = Math.max(nowLastIndex, charLastIndex[sChar[i] - 'a']);  // 如果当前位置是当前字符集中所有字符最后出现的位置  if (i == nowLastIndex) {  // 将当前分区长度(当前位置与上一个分区结束位置之差)加入结果列表  result.add(i - lastEndIndex);  // 更新上一个分区的结束位置为当前位置  lastEndIndex = i;  }  }  // 返回分区长度的列表  return result;  }  
}

56.合并区间 

56. 合并区间

中等

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示:

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

 思路:首先对数组排序。从第二个区间开始遍历,如果和前一个区间有交集,就将该区间更新为与前一个区间的并集。如果和前一个区间没有交集,则前一个区间为合并好的区间,放入结果集合中,如果遍历到最后一个区间,直接将最后一个区间放入结果数组中。

class Solution {  public int[][] merge(int[][] intervals) {  // 根据区间的起始位置对数组进行排序  Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));  // 用于存储合并后结果的列表  List<int[]> result = new ArrayList<>();  // 如果区间数组为空或只有一个区间,则无需合并,直接返回原数组  if (intervals.length < 2 || intervals == null) {  return intervals;  }  // 从第二个区间开始遍历(第一个区间不需要比较)  for (int i = 1; i < intervals.length; i++) {  // 如果当前区间的起始位置大于前一个区间的结束位置,说明两个区间没有重叠  if (intervals[i][0] > intervals[i - 1][1]) {  // 将前一个区间添加到结果列表中  result.add(intervals[i - 1]);  } else {  // 两个区间有重叠,合并这两个区间  // 更新当前区间的起始位置为两个区间中较小的起始位置  intervals[i][0] = intervals[i - 1][0];  // 更新当前区间的结束位置为两个区间中较大的结束位置  intervals[i][1] = Math.max(intervals[i][1], intervals[i - 1][1]);  }  // 如果是遍历的最后一个区间,则需要将其添加到结果列表中  // 因为如果两个区间有重叠,它们会在下一个循环迭代中被合并,当前区间不会在前面的迭代中被添加到结果列表  if (i == intervals.length - 1) {  result.add(intervals[i]);  }  }  // 将结果列表转换为数组并返回  return result.toArray(new int[result.size()][]);  }  
}

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

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

相关文章

【AI】举例说明计算机视觉(CV)技术的优势和挑战。

计算机视觉&#xff08;CV&#xff09;技术是一种让计算机能够理解和解释图像和视频内容的技术。以下是计算机视觉技术的优势和挑战的一些例子&#xff1a; 优势&#xff1a; 自动化处理&#xff1a;计算机视觉技术可以实现自动化处理&#xff0c;大大节省了人力成本和时间成本…

Linux下ifconfig,netstat 无法正常使用解决办法

yum install -y net-toolsifconfig替代查询命令&#xff1a; 查看网络接口信息&#xff1a; ip addr show显示某个特定接口&#xff08;例如eth0&#xff09;的详细信息&#xff1a; ip addr show eth0&#xff08;实际网卡名&#xff09;查看网络接口统计信息&#xff1a; ip …

JAVA中已有的栈和队列的实现

在Java中&#xff0c;有多种方式可以实现栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;的数据结构。以下是一些主要的实现方式&#xff1a; 1. 栈&#xff08;Stack&#xff09; 使用java.util.Stack类&#xff1a; java.util.Stack是Java提供的一个基…

基于springboot实现成人教育教务系统项目【项目源码+论文说明】

基于springboot实现成人教育教务系统演示 摘要 随着市场经济的产业化结构升级&#xff0c;人才结构也在不断发生这巨大的变化和变革。而且各大企业都在处于一个高速发展和壮大的阶段&#xff0c;在这个高速发展和结构化升级的时期对于人才的需求也在不断的增多。企业和用工单位…

Git高级玩法:Rebase、Cherry-pick与Stash实战解析

Git高级功能&#xff1a;理解Rebase、Cherry-pick与Stash 在软件开发过程中&#xff0c;Git作为版本控制系统&#xff0c;已经成为不可或缺的工具。而Git的高级功能&#xff0c;如Rebase、Cherry-pick与Stash&#xff0c;为开发者提供了更多的灵活性和便利性。本文将详细介绍这…

uView ui 安装步骤

uView是uni-app生态优秀的UI框架 安装说明 由于uView使用easycom模式&#xff0c;让您无需引入组件即可直接使用&#xff0c;但是此功能需要Hbuilder X 2.5.5及以上版本才支持&#xff0c;详见配置easycom组件模式。 easycom打包的时候是按需引入的&#xff0c;您可以放心引入…

关于应用程序自卸载能力的探讨

在当前数字化的时代背景下&#xff0c;应用程序的安装与卸载已成为我们日常生活及工作中常见的操作行为。对于“应用程序能否自我卸载”这一议题&#xff0c;引发了科技领域和广大用户群体的关注与讨论。本文将围绕该主题展开深入剖析&#xff0c;探究其实质内涵以及其可能产生…

【Python】新手入门学习:详细介绍组合/聚合复用原则(CARP)及其作用、代码示例

【Python】新手入门学习&#xff1a;详细介绍组合/聚合复用原则&#xff08;CARP&#xff09;及其作用、代码示例 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集…

Nmap最常用命令(非常详细)零基础入门到精通,收藏这一篇就够了

nmap是我们最常用的工具。但是命令太多了&#xff0c;没办法全部记下。我们在实际工作中只需要记住最常用的几条命令就行了。 主机发现 里面nmap&#xff0c;我们可以扫描在同一局域网内有哪些设备在线。常用命令如下&#xff1a; nmap 192.168.50.1/24 -sL 上面命令&#…

羊大师分析,羊奶和牛奶哪个更有营养

羊大师分析&#xff0c;羊奶和牛奶哪个更有营养 羊奶和牛奶都是营养丰富的奶制品&#xff0c;它们各自具有独特的营养价值和特点&#xff0c;因此无法简单地判断哪个更有营养。 羊奶中含有较高的脂肪和蛋白质&#xff0c;同时富含矿物质和维生素&#xff0c;如钙、磷、铁、锌以…

JSON 转换问题 $ref“: “$[0].list[1]

现象 [{"delete": false,"index": 0,"list": [{"duration": 71000,"id": 0,"mediumId": 9231114101362,"path": "","point": 100,"title": "垃圾"},{"d…

python | 类与对象

在 Python 中&#xff0c;我们用关键字 class 来定义类&#xff1a; class Player:pass Player 类中只有一条语句 pass&#xff0c;这是 Python 中的特殊语句&#xff0c;没有实际含义。 Python 在执行到它时也什么都不会做。不过它能够保证结构的完整性。例如&#xff0c;我…

揭秘FastStone Capture:一款强大且高效的截图工具

目录 【引子】【FastStone Capture概述】【安装步骤】【使用攻略】【核心功能解析】【总结】 【引子】 在数字化信息时代&#xff0c;无论是工作汇报、在线教学&#xff0c;还是日常交流中&#xff0c;屏幕截图已经成为我们必不可少的辅助工具。今天&#xff0c;我要为大家详细…

git svn混用

背景 项目代码管理初始使用的svn, 由于svn代码操作&#xff0c;无法在本地暂存&#xff0c;有诸多不便&#xff0c;另外本人习惯使用git. 所以决定迁移至git管理 迁移要求&#xff1a; 保留历史提交记录 迁移流程 代码检出 git svn svn_project_url git代码提交 修改本…

编写应用程序,输出满足1+2+3+~+n<8888的最大正整数n

/** * 寻找满足条件的最大整数。 * 程序通过累加整数&#xff0c;直到累加和大于等于给定值&#xff08;8888&#xff09;为止&#xff0c;然后输出满足条件的最大整数。 */ public class E { public static void main(String args[]){ int n1; // 从1开始累加整…

得物布局构建耗时优化方案实践

一、背景 当谈到移动应用程序的体验时&#xff0c;页面启动速度是其中至关重要的一点&#xff0c;更快的页面展示速度确保应用程序可以迅速加载并响应用户的操作, 从而提高用户使用 App 时的满意度。在页面启动的整个流程中&#xff0c;随着 UI 复杂度的上升&#xff0c;布局的…

高速口光口通信

1.通过transceiver ip 设置好硬件连接配置 2.open example 用自己的模块替换掉tx和rx数据模块 三&#xff1a;相关信号&#xff1a; 1:tx/rx_rset_done1表示初始化完成

【Java探索之旅】解密Java中的类型转换与类型提升

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java编程秘籍 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、类型转化1.1 自动类型转换&#xff08;隐式类型转换&#xff09;1.2 强制类型转换…

Arduino IDE的下载和安装

一、Arduino的介绍 Arduino是一款开源电子原型平台&#xff0c;主要包含两部分&#xff1a;硬件&#xff08;各种型号的Arduino板&#xff09;和软件&#xff08;Arduino IDE&#xff09;。这个平台由意大利的Massimo Banzi、David Cuartielles等人共同开发设计&#xff0c;并于…

ES分片均衡策略分析与改进

从故障说起 某日早高峰收到 Elasticsearch 大量查询超时告警&#xff0c;不同于以往&#xff0c;查看 Elasticsearch 查询队列监控后发现&#xff0c;仅123节点存在大量查询请求堆积。 各节点查询队列堆积情况 查看节点监控发现&#xff0c;123节点的 IO 占用远高于其他节点。…