类似于区间调度问题,使用贪心算法:首先对所有气球按照起始坐标大小排序,然后每次总是优先选择起始坐标小的气球中的右边坐标,然后再选择下一个;
排完序之后,下一个可能有如上图所示几种情况,
1) 当next.end<t时,此时一定有next.start>start且next.start<t, 应该令t=next.end这样可以节省一支箭;
2) 当next.end>t且next.start<end, 此时一定可以射爆next,参考虚线最顶端的气球;
3) 当next.start>t时,此时一定需要增加一支箭来射穿next, 且当前的箭不能再多射中气球;
class Solution { public: static bool cmp(pair<int,int>a, pair<int,int>b ){ return a.first<b.first; } int findMinArrowShots(vector<pair<int, int>>& points) { sort(points.begin(),points.end(),cmp); int len=points.size(); //空points边界判定 if(len==0) return 0; /*** 1) 当next.end<t时,此时一定有next.start>start且next.start<t, 应该令t=next.end这样可以节省一支箭; 2) 当next.end>t且next.start<end, 此时一定可以射爆next,参考虚线最顶端的气球; 3) 当next.start>t时,此时一定需要增加一支箭来射穿next, 且当前的箭不能再多射中气球;***/ int t=points[0].second; int cnt=1; for(int i=1;i<len;i++){ //1),2)可以认为下一个if不成立时选end最小值; if(points[i].second<t){ t=points[i].second; //cout<<"1: "<<t<<endl; } //符合3的情况,必须多一支箭 if(t<points[i].first){ cnt++;t=points[i].second; //cout<<"2: "<<t<<endl; } } return cnt; } };