專欄 | 九章算法
網址 | 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相關問題
推薦閱讀: