LeetCode452.Minimum Number of Arrows to Burst Balloons

原题链接:https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/ 题目大意为给你一堆气球,这些气球沿X轴方向摆放,每个气球大小可能不同,一个气球占据的区间可以表示为[Xstart,Xend],气球可以重叠摆放。一支坐标为x的箭,可以扎破所有满足 Xstart <= x <= Xend 的气球,求出最少射几支箭可以将所有气球扎破。

  这道题可以采用贪心策略来解决。起先我考虑的首先选择能扎破最多气球数的箭,然后在剩下的气球中再次选择扎破最多的箭直到所有气球全扎破,但是这种选择顺序可能让气球的分布更分散,反而增加了需要射出的箭的数量。由于不同气球摆放的位置可能会有部分重叠,显然相互重叠的气球更可能被同时扎破。虽然题目中给出的表示气球的数组points看不出气球摆放的顺序,但是我们可以对points数组按一定顺序排序,即先按Xstart的大小排序,再按Xend的大小排序,对排完序的points数组,采取的贪心策略就是:从points中的第一个气球开始,遍历points数组,如果第 i 个气球和前 i-1 个气球都有重叠,则它们是可以在一次射击里被一起扎破的;直到出现某个气球与它之前的某个气球完全不重叠,表示需要射出另外一支箭。按这个策略遍历下去直到最后一个气球。代码实现如下:

 1 import java.util.Arrays;
 2 
 3 public class LeetCode452 {
 4     public int findMinArrowShots(int[][] points) {
 5         if (points == null || points.length == 0)
 6             return 0;
 7         Arrays.sort(points, (a, b) -> {return a[0] - b[0] == 0 ? a[1] - b[1] : a[0] - b[0];});
 8         int arrows = 1;
 9         int endindex = points[0][1];
10         for (int i = 1; i < points.length; i++) {
11             if (points[i][0] <= endindex) {
12                 endindex = endindex < points[i][1] ? endindex : points[i][1];
13             } else {
14                 arrows++;
15                 endindex = points[i][1];
16             }
17         }
18         return arrows;
19     }
20 }

 

注:第7行是JDK8中用Lambda表达式来实例化一个comparator接口;算法的时间复杂度是排序O(nlgn),遍历O(n)。

posted @ 2016-11-20 21:15  栗子拉面酱  阅读(859)  评论(0编辑  收藏  举报