【JS每日一算法:剑指Offer系列】🟨166. 用最少数量的箭引爆气球(排序+贪心)

75 阅读3分钟

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 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

题解:

个人博客

更多JS版本题解点击链接关注该仓库👀

/**
 * @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;
}