【算法之贪心算法IV】leetcode56. 合并区间

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

力扣题目链接

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

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

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

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

解题思路

  1. 按照结束边界进行排序
  2. 如果前一个结束边界和后一个开始边界不相交,使用箭的数量加一,更新边界值。
  3. 不能用数值相减来判断大小,可能会出现出界的情况。

Java实现

方式一

class Solution {public int findMinArrowShots(int[][] points) {Arrays.sort(points, new Comparator<int[]>() {@Overridepublic int compare(int[] point1, int[] point2) {return point1[1] < point2[1] ? -1 : 1;}});int pos = points[0][1];int ans = 1;for (int i = 1; i < points.length; i++) {if (points[i][0] > pos) {ans++;pos = points[i][1];}}return ans;}
}

方式二

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

435. 无重叠区间

力扣题目链接

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

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

解决思路

  1. 使用动态规划,res[i]表示以第i个区间为结束区间,最大的不重叠区间的个数。公式推导。
  2. 贪心算法。

Java实现

方式一:

class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals, new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {return Integer.compare(o1[1], o2[1]);}});int n = intervals.length;int pos = intervals[0][1];int res = 1;for (int i = 1; i < n; i++) {if (intervals[i][0] >= pos) {res++;pos = intervals[i][1];}}return n - res;}
}

方式二:

class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals, new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {return Integer.compare(o1[0], o2[0]);}});int n = intervals.length;int[] res = new int[n];Arrays.fill(res, 1);for (int i = 1; i < n; i++) {for (int j = 0; j < i; j++) {if (intervals[j][1] <= intervals[i][0]) {res[i] = Math.max(res[j] + 1, res[i]);}}}return n - Arrays.stream(res).max().getAsInt();}
}

763.划分字母区间

力扣题目链接

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

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

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

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

解决思路

  1. 保证所有出现的字符最开始的元素和最后的元素都在一个片段中。

Java实现

class Solution {public List<Integer> partitionLabels(String s) {int start=0, end = 0;int len = s.length();int[] data = new int[26];List<Integer> res = new ArrayList<>();for (int i = 0; i < s.length(); i++) {data[s.charAt(i) - 'a'] = i;}for (int i = 0; i < len; i++) {end = Math.max(data[s.charAt(i) - 'a'], end);if (i == end) {res.add(end - start + 1);start = end + 1;}}return res;}
}

56. 合并区间

力扣题目链接

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

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

解决思路

  1. 使用链表。判断是否有重合区间。

Java区间

class Solution {public int[][] merge(int[][] intervals) {LinkedList<int[]> res = new LinkedList<>();Arrays.sort(intervals, (a, b) -> {return Integer.compare(a[0], b[0]);});res.add(intervals[0]);for (int i = 1; i < intervals.length; i++) {if (intervals[i][0] <= res.getLast()[1]) {res.getLast()[1] = Math.max(res.getLast()[1], intervals[i][1]);} else {res.add(intervals[i]);}}return res.toArray(new int[res.size()][]);}
}

738.单调递增的数字

力扣题目链接

当且仅当每个相邻位数上的数字 xy 满足 x <= y 时,我们称这个整数是单调递增的。

给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增

输入: n = 332
输出: 299

解决思路

  1. 找到数组中第一个元素比前面一个元素小的
  2. 前面一个元素的值减一,start--,直到前面元素小于等于当前元素。
  3. 更新start+1到最后的元素,都改为9。
  4. 1221的最大元素是1199

Java实现

class Solution {public int monotoneIncreasingDigits(int n) {String s = String.valueOf(n);char[] chars = s.toCharArray();int start = 1;while (start < s.length() && chars[start - 1] <= chars[start]) {start++;}//找到数组中第一个元素比前一个元素大if (start < s.length()) {while (start > 0 && chars[start - 1] > chars[start]) {chars[start - 1]--;start--;}for (int i = start + 1; i < chars.length; i++) {chars[i] = '9';}}return Integer.parseInt(new String(chars));}
}

968.监控二叉树

力扣题目链接

给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。

输入:[0,0,null,0,0]
输出:1
解释:如图所示,一台摄像头足以监控所有节点。

解决思路

  1. 覆盖就是当前节点是否被照亮。
  2. 当子节点有一个没有被覆盖,那么当前节点必须要点灯;当子节点都亮了,那么当前节点最好是无覆盖(当前节点在当前子树上是无覆盖的,如果还有父节点,让父节点点灯;如果当前节点是根节点,根据定义,根节点也需要点灯)

Java实现

class Solution {int count = 0;public int minCameraCover(TreeNode root) {if (minCame(root) == 0) {count++;}return count;}/*** 0  无覆盖  1 有摄像头   2  覆盖** @param root* @return*/public int minCame(TreeNode root) {if (root == null) {//空节点默认是有覆盖,避免在叶子节点上放摄像头return 2;}int left = minCame(root.left);int right = minCame(root.right);if (left == 2 && right == 2) {return 0;} else if (left == 0 || right == 0) {count++;return 1;} else {return 2;}}
}

在这里插入图片描述

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

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

相关文章

IDEA字体配置

IDEA默认字体&#xff1a;JetBrains Mono 1、下载Monaco字体&#xff08;windows版&#xff09;&#xff1a;下载地址&#x1f448; 2、双击安装 3、在IDEA中切换Monaco字体

C++ DAY3

1.思维导图 2.有以下类定义&#xff0c;按要求实现剩余功能 #include <iostream> using namespace std;class Person { private:int age;int *p; public://无参构造Person():p(new int(89)){age 18;}//有参构造Person(int age,int num){this->age age;this->pne…

【MySQL】SQL的函数用法

文章目录 聚合函数Count()Max()Min()Sum()Avg() 其他常用函数时间函数字符串函数SUBSTRING函数:切割字符串([start:end])SUBSTRING_INDEX函数:切割字符串(split)LOWER&UPPER函数:大小写转化CONCAT&CONCAT_WS函数:连接字符串REPLACE函数:字符串替换 数学函数ROUND函数:四…

Spring Boot高阶篇笔记

一、Spring Boot整合Redis缓存 JSR-107、Spring缓存抽象、整合Redis 1、JSR107 Java Caching定义了5个核心接口&#xff0c;分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry。 • CachingProvider定义了创建、配置、获取、管理和控制多个CacheManager。一个应…

一点基础、但一直没分清的概念2023/06/28

文章目录 1.export和export default的区别2.npm和cnpm的区别3.npm run dev/serve的区别4.slice、splice和split的区别 1.export和export default的区别 模块功能主要由两个命令构成&#xff1a;export和import。export命令用于规定模块的对外接口&#xff0c;import命令用于输…

MySQL事务与存储引擎

MySQL事务与存储引擎 MySQL事务一、事务的概念二、事务的ACID特点1、原子性2、一致性3、隔离性4、持久性&#xff08;Durability&#xff09;总结 三、事务之间的相互影响1、脏读2、不可重复读3、幻读4、丢失更新 四、Mysql及事物隔离级别1、查询全局事务隔离级别2、查询会话事…

npm 包 - serve 使用

前端打包后&#xff0c;或者本地的html文件。有时需要将打包好的项目跑一下看看效果&#xff0c;这时就可以使用 serve 工具&#xff0c;在本地启动一个静态文件服务器。本文主要简单记录下 npm 包 serve 的基本使用命令。 一、全局安装 serve npm install serve -g二、运行 s…

文心一言眼里的Java世界

目录 一、Java基础教程系列二、先听听文心一言怎么说&#xff1f;三、话不多说&#xff0c;开干。1、要有一个正确的Java学习路线&#xff0c;做一个细致的Java学习规划。2、学习资料推荐3、书中自有黄金屋&#xff0c;书中自有颜如玉4、自学周期推荐5、效率为先6、哪吒的学习方…

【深度学习】2-1 神经网络 - 激活函数

激活函数 将输入信号的总和转换为输出信号&#xff0c;一般称为激活函数&#xff08;activation function&#xff09;。激活函数作用在于决定如何来激活输入信号的总和。 对激活函数&#xff0c;一般要求&#xff1a; 非线性&#xff1a;为提高模型的学习能力&#xff0c;如…

机器学习李宏毅学习笔记33

文章目录 前言一、神经网络压缩二、Network pruning----一种network compression技术1.移除不同单位的区别2.大乐透假说 总结 前言 神经网络压缩&#xff08;一&#xff09; 类神经网络剪枝&#xff08;pruning&#xff09; 一、神经网络压缩 简化模型&#xff0c;用比较少的…

软件安全技术复习内容

软件安全技术 边复习边写的&#xff0c;有错误及时指正第一章 软件安全概述零日漏洞安全威胁分类CIA安全基本属性PDRR模型软件安全的主要方法和技术基本方法主要技术 第二章 软件漏洞概述概念软件漏洞成因分析软件漏洞分类基于漏洞成因的分类基于漏洞利用位置的分类基于威胁类型…

【工作记录】基于CSS+JS可拖拽改变大小、可吸附到边界的DIV

记录一段实现可拖拽、可自动吸附到边界的代码。 <!DOCTYPE html> <html lang"en"> <head><style>body {overflow: hidden;}#pane {position: absolute;width: 45%;height: 45%;top: 20%;left: 20%;margin: 0;padding: 0;z-index: 99;border…