[LeetCode] 452. Minimum Number of Arrows to Burst Balloons

There are some spherical balloons taped onto a flat wall that represents the XY-plane. The balloons are represented as a 2D integer array points where points[i] = [xstart, xend] denotes a balloon whose horizontal diameter stretches between xstart and xend. You do not know the exact y-coordinates of the balloons.

Arrows can be shot up directly vertically (in the positive y-direction) from different points along the x-axis. A balloon with xstart and xend is burst by an arrow shot at x if xstart <= x <= xend. There is no limit to the number of arrows that can be shot. A shot arrow keeps traveling up infinitely, bursting any balloons in its path.

Given the array points, return the minimum number of arrows that must be shot to burst all balloons.

Example 1:

Input: points = [[10,16],[2,8],[1,6],[7,12]]
Output: 2
Explanation: The balloons can be burst by 2 arrows:
- Shoot an arrow at x = 6, bursting the balloons [2,8] and [1,6].
- Shoot an arrow at x = 11, bursting the balloons [10,16] and [7,12].

Example 2:

Input: points = [[1,2],[3,4],[5,6],[7,8]]
Output: 4
Explanation: One arrow needs to be shot for each balloon for a total of 4 arrows.

Example 3:

Input: points = [[1,2],[2,3],[3,4],[4,5]]
Output: 2
Explanation: The balloons can be burst by 2 arrows:
- Shoot an arrow at x = 2, bursting the balloons [1,2] and [2,3].
- Shoot an arrow at x = 4, bursting the balloons [3,4] and [4,5].

Constraints:

  • 1 <= points.length <= 105
  • points[i].length == 2
  • -231 <= xstart < xend <= 231 - 1

用最少数量的箭引爆气球。

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

给一个数组,数组里面存的是类似 [left, right] 这样的区间,left 和 right 分别代表气球直径的起点和终点。求问如果要引爆所有的气球最少需要几只箭。

这个题依然用到了扫描线的思想,而且思路基本等同于会议室二。先对所有气球直径的终点排序,然后以第一个气球的终点为起点开始看,如果第二个气球的起点大于第一个气球的终点,就说明两个气球不重叠,则需要另一个箭;同时挪动指针到第二个气球的终点。

时间O(nlogn) - 对 input 排序

空间O(1)

JavaScript实现

 1 /**
 2  * @param {number[][]} points
 3  * @return {number}
 4  */
 5 var findMinArrowShots = function (points) {
 6     // corner case
 7     if (points === null || points.length === 0) return 0;
 8 
 9     // normal case
10     points = points.sort((a, b) => a[1] - b[1]);
11     let res = 1;
12     let firstEnd = points[0][1];
13     for (let i = 1; i < points.length; i++) {
14         if (points[i][0] > firstEnd) {
15             res++;
16             firstEnd = points[i][1];
17         }
18     }
19     return res;
20 };

 

Java实现,注意test case中会给出包含 Integer.MAX_VALUE 和 Integer.MIN_VALUE 的区间,所以只能用 Integer.compare 。单纯的sort会出错。

 1 class Solution {
 2     public int findMinArrowShots(int[][] points) {
 3         int len = points.length;
 4         // corner case
 5         if (points == null || len == 0) {
 6             return 0;
 7         }
 8         
 9         // normal case
10         Arrays.sort(points, (a, b) -> Integer.compare(a[1], b[1]));
11         int res = 1;
12         int end = points[0][1];
13         for (int i = 1; i < len; i++) {
14             if (end < points[i][0]) {
15                 res++;
16                 end = points[i][1];
17             }
18         }
19         return res;
20     }
21 }

 

扫描线相关题目

LeetCode 题目总结

posted @ 2020-03-04 13:09  CNoodle  阅读(266)  评论(0编辑  收藏  举报