题目描述:
有一些球形气球贴在一堵用 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();}
}