专栏 | 九章算法
网址 | www.jiuzhang.com程序员
题目描述面试
在二维空间中的一组气球,给出每一个气球的横向直径的起始横坐标和结束横坐标,保证起始横坐标小于结束横坐标。算法
不须要考虑气球的纵坐标,所以横坐标区间能够相互重叠。气球最多有10000个。一支箭能够选定一个横坐标纵向射击。编程
一个气球的横向直径两端横坐标为xbegin,xend,一支箭射击的横坐标为x,若是有xbegin<=x<=xend,则这支箭能够刺破该气球。没有箭的使用数量限制,而且一支箭能够刺破相应坐标上的全部气球。微信
求出刺破全部气球所需的最少的箭的数量。编程语言
样例post
输入: [[10,16], [2,8], [1,6], [7,12]]ui
输出: 23d
说明:
一种方案是在坐标x=6射一支箭(能够刺破气球[2,8]和[1,6]),
在坐标x=11射另外一只箭(刺破剩下的两个气球)code
解题思路分析
a. 考虑n个区间[s(i), f(i)],i=1,2,……,n,表示n个气球的横向直径的左右端点所表示的区间。若是它们全都互相重叠,那么就能够在它们的相交区间上取一点射箭,这支箭便可刺破全部气球。若是存在互不重叠的区间,那么为了将这些区间的气球刺破,就不得不在这些区间中各射一支箭。
假设区间右端点坐标f(1),f(2),……,f(n),已按从小到大排序,对于这类在一个轴上的区间问题,咱们经常使用的思路是按照左(右)端点排序。考虑第一个区间(右端点坐标f(1)最小的区间),至少要用一支箭将该区间的气球刺破,那么这支箭射在什么位置可使它刺破尽量多的气球呢?
答案是区间的右端点坐标。事实上,对于射在任何坐标x<f(1)上的箭能刺破的气球,射在f(1)上必定能刺破,由于f(1)是全部右端点中最小的,在x上能刺破的气球右端点也不会小于f(1)。
这样咱们就获得了一个贪心的策略:先按区间右端点f(i)排序,从左往右扫描区间,取出当前右端点坐标最小的区间,在该区间右端点坐标x射出一箭,答案加1,继续日后扫描,去掉全部能被这支箭刺破的气球(s(i)<=x的气球均能被刺破),直到搜索到下一个不能被这只箭刺破的气球,再用一样的方式处理。时间复杂度为排序的时间复杂度O(n*log(n))。
b. Follow up:
本题的输出答案与全部区间中能选出的最多的互不重叠的区间的个数有什么关系?
参考程序
面试官角度分析
这题与经典的活动选择问题十分类似,解法是贪心算法,能有清晰的思路并给出解答便可hire。
lintcode相关问题
推荐阅读: