力扣452. 用最少数量的箭引爆气球
题目来源(力扣):
https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/description/
题目描述:
给出若干个圆形气球在x坐标轴上的左右区间,选择尽可能少的点来射箭,使得能够射爆所有气球。
基本思路:
贪心算法。
对所有气球按左区间排序,气球间会构成公共区域[l,r]。
遍历拍好序的气球i,如果他的左区间位于[l,r]之间,则说明其位于公共区域(可以只用1支箭射穿位于公共区域中的所有气球),更新l与r而无需使用更多箭;
如果气球i的左区间不在[l,r]中,说明形成了新的公共区域,需要新的箭头。
具体可见代码:
代码实现:
class Solution
{
public:
static bool cmp(pair<int, int> A, pair<int, int> B)
{
return A.first < B.first;
}
int findMinArrowShots(vector<vector<int>> &points)
{
vector<pair<int, int>> p;
int len = points.size();
for (int i = 0; i < len; i++)
{
p.push_back(make_pair(points[i][0], points[i][1]));
}
sort(p.begin(), p.end(), cmp);
// for(int i=0;i<len;i++){
// cout<<p[i].first<<" "<<p[i].second<<endl;
// }//ok
int l, r;
int tot = 1;//设置第一个气球为初始区间
l = p[0].first, r = p[0].second;
for (int i = 1; i < len; i++)
{
if (p[i].first > r)//形成新的区域,说明需要一个新的箭头
{
++tot;
l = p[i].first, r = p[i].second;
}
else//说明还在当前的公共区域中,继续使用旧箭头即可,更新[l,r]
{
//l = max(l, p[i].first); //可以不写,因为用不到;而且实际上总是会使得 l更新为p[i].second,因为是按照p[i].first升序sort的
r = min(r, p[i].second);
}
}
return tot;
}
};
时间复杂度
O(nlogn)
主要花费在sort排序上面,时间复杂度O(nlogn)
而贪心遍历的过程是o(n)的,
总时间复杂度就是O(nlogn+n),即O(nlogn)
浙公网安备 33010602011771号