用最少的箭引爆氣球 題解(個人理解)leetcode-452
阿新 • • 發佈:2020-11-25
題目描述
在二維空間中有許多球形的氣球。對於每個氣球,提供的輸入是水平方向上,氣球直徑的開始和結束座標。由於它是水平的,所以縱座標並不重要,因此只要知道開始和結束的橫座標就足夠了。開始座標總是小於結束座標。
一支弓箭可以沿著 x 軸從不同點完全垂直地射出。在座標 x 處射出一支箭,若有一個氣球的直徑的開始和結束座標為 xstart,xend, 且滿足 xstart ≤ x ≤ xend,則該氣球會被引爆。可以射出的弓箭的數量沒有限制。 弓箭一旦被射出之後,可以無限地前進。我們想找到使得所有氣球全部被引爆,所需的弓箭的最小數量。
給你一個數組 points ,其中 points [i] = [xstart,xend] ,返回引爆所有氣球所必須射出的最小弓箭數。
連結:https://leetcode-cn.com/problems/minimum-number-of-arrows-to-burst-balloons
概括:排序,貪心,重疊區間
示例程式碼(java)
1 class Solution { 2 public int findMinArrowShots(int[][] points) {//二維陣列儲存氣球的左邊界,右邊界 int[a][b]中,a表示氣球標號;b是0或1,0表示左邊界,1表示右邊界,而值當然是邊界值。 3 if (points.length == 0) {//如果二維陣列為空,返回零 4 return0; 5 } 6 Arrays.sort(points, new Comparator<int[]>() {//匿名內部類實現comparator介面 自定義compare方法(return值大於零則會交換)達到的效果是 按氣球的右邊界升序排列 7 public int compare(int[] point1, int[] point2) {//重寫compare方法,point1[],point2[]都是型參 8 if (point1[1] > point2[1]) { 9 return1;//返回值大於0,換位置 10 } else if (point1[1] < point2[1]) { 11 return -1;//不變 12 } else { 13 return 0;//不變 14 } 15 } 16 }); 17 int pos = points[0][1];//定義第一根箭的位置 18 int ans = 1;//數量初值為1 19 for (int[] balloon: points) {//迴圈(一維陣列balloon[]裝的是左(0)右(1)邊界的值) 20 if (balloon[0] > pos) {//如果左值大於之前的右值,證明之前箭射不爆這個氣球 21 pos = balloon[1];//再來一箭,攻擊這個氣球的右邊界 22 ++ans;//箭數加一 23 } 24 } 25 return ans; 26 } 27 }
示例程式碼2(java)
class Solution {//摘自一位被不講武德的力扣偷襲的996碼農 public int findMinArrowShots(int[][] points) { if(points.length == 0) return 0; Arrays.sort(points, (p1, p2) -> p1[1] < p2[1] ? -1 : 1);//使用lambda表示式代替匿名內部類,簡單! int res = 1; int pre = points[0][1]; for (int i = 1; i < points.length; i++) {//樸實無華,一看就懂 if (points[i][0] > pre) { res++; pre = points[i][1]; } } return res; } }
關於:
1.貪心演算法
①根據 結束位置,從小到大 排序原陣列
②貪心,遍歷陣列,計算結果:
由於原陣列根據 結束位置,從小到大 排序
因此,我們只用判斷 當前氣球的開始位置 和 當前區間的結束位置 大小關係:
>若 當前氣球的開始位置 < 當前區間的結束位置,則表示當前氣球也在當前區間內
>若 不滿足上述條件,則當前氣球不在當前區間內,箭數+1,更新當前區間的結束位置
2.測試用例
[[-2147483646,-2147483645],[2147483646,2147483647]]
不講武德,我勸,所有comparator裡compare返回值用減法的年輕人
耗子尾汁,好好反思,謝謝朋友們!