有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 x``start,x``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 <= 105points[i].length == 2-231 <= xstart < xend <= 231 - 1
题解:
/**
* @description: 贪心 TC:O(nlogn) SC:O(1)
* @author: JunLiangWang
* @param {*} points 给定数组
* @return {*}
*/
function sortAndGreedy(points) {
/**
* 本方案使用排序+贪心的方案,首先根据数组x开始位置
* 进行升序排序,如下例子:
* 原数组: [[2,3],[4,6],[1,5],[3,7]]
* 排序后: [[1,5],[2,3],[3,7],[4,6]]
*
* 如何合并其交集呢?其实就是前一个元素的结束位置,是
* 否超过了后一个元素的开始位置,如果超过则证明两元素
* 有交集,没有超过证明无交集。其交集范围则为:
* [后一个元素的start,Min(两元素的end)]
* 由于是根据start排序的,后一个元素的star肯定是大于
* 等于前一个元素的。
*
*
*/
// 如果元素个数小于等于1,直接返回元素个数即可
if (points.length <= 1) return points.length
// 根据元素的开始位置,对数组进行排序
points.sort((a, b) => a[0] - b[0])
// 记录当前交集的end位置
let end = points[0][1],
// 记录当前有多少无交集元素,由于从1开始的,因此初始化为1
count = 1;
// 从1遍历数组元素
for (let i = 1; i < points.length; i++) {
// 如果当前交集的结束位置,超过了后一个元素的开始位置
// 证明两者还存在交集,此时更新两者交集的结束位置
if (end >= points[i][0]) end = Math.min(points[i][1], end)
// 反之则没有交集
else {
// count+1
count++;
// 将当前交集结束位置更新为当前元素的结束位置
end = points[i][1]
}
}
// 返回结果
return count;
}