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

题目描述:
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。

题目链接

解题思路:思路不唯一,我就是把这道题变相成合并区间,并且是求区间的交集,因为射箭是在交集才能一箭N中,具体步骤见注释~

代码实现

class Solution {
    /**
     * 1. 先将二维数组按照左区间从小到大进行排序
     * 2. 合并区间,当发现左区间有重合的时候,需要将右边界更新为小的那个,因为要和下一个区间比较,保证三个都有相交的才行
     * 3. 返回二维区间的秩即可
     */
    public int findMinArrowShots(int[][] points) {
        // 本质是区间合并,不一样的是当发现左区间有重合的时候,需要将右边界更新为小的那个,因为要和下一个区间比较,保证三个都有相交的才行
        Arrays.sort(points,(x,y) -> Integer.compare(x[0], y[0]));
        // 新建一个二维数组,存放合并后的新的区间
        List<int[]> res = new LinkedList<int[]>();
        int m = points.length;
        int start = 0;
        int end = 0;
        int k = 1;
        res.add(points[0]);
        while (k < m) {
            // 先判断右边界是否 > 下一个的左边界
            if (points[k][0] > res.get(res.size()-1)[1]){//无相交,则直接加进去
                res.add(points[k]);
            }else {// 有相交,找两个区间的交集,也就是箭可以射的区间
                start = Math.max(points[k][0], res.get(res.size()-1)[0]);// 左区间找最大
                end = Math.min(points[k][1], res.get(res.size()-1)[1]);// 右区间找最小
                res.remove(res.size()-1);// 需要先移除最后一个,再添加,不然就重复了
                res.add(new int[]{start,end});
            }
            k++;
        }
//        for (int i = 0; i < res.size(); i++) {
//            System.out.println(Arrays.toString(res.get(i)));
//        }
        return res.size();
    }
}

你可能感兴趣的:(LeetCode,leetcode)