【贪心算法】452用最少数量的箭引爆气球
题目
解析
这道题,首先看题目,给出最少的字眼,那么初步判断用的是贪心算法。
分析这道题目,可以看到的是,要想箭的数量最少,那么就要求这些区间拥有一个公共区间(这个公共区间由若干个区间堆叠形成的,越多越好)
那么,我只要遍历这些区间,然后找公共区间
下面我给出题目中的案例,演示一下:
[[1,6],[2,8],[7,12],[10,12]],首先将这些区间按照起始点进行排序,然后从第一个区间开始,设置pre = points[0][1], 将pre
与points[i][0]进行比较,也就是[1,6] 区间的6端点与[2,8]区间的2端点进行比较,那么,2 < 6 说明重叠,那么这时候,你就需要开始找公共区间了
你可以一眼看到公共区间是[2,6], 那么你可以断定公共区间的左端点一定是第二个区间的左端点, 但是公共区间的右端点是不是第二个区间的右端点呢?这里显然不是,
这里是第一个区间的右端点,所以是不是选择两个区间较小的右端点呢? 答案是肯定的。
代码
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
// 最少 一般使用贪心算法
// 找出 最多区间重叠个数:这些重叠区间都有公共区间
if(points.size() == 1)
{
return 1;
}
// 将数组的所有区间按照左端点进行排序
sort(points.begin(),points.end());
int res = 1;
int pre = points[0][1]; // 拿出第一个区间的右端点
for(int i = 1; i < points.size(); i++)
{
// 将第二个区间的左端点与第一个区间的右端点进行比较
if(pre < points[i][0])
{
// 说明不重叠
res++;
pre = points[i][1]; // 更新为第二个区间的右端点
}
else
{
// 如果重叠
// 最终的目的是找出所有区间的公共区间
// 我们可以看到题目给出的例子 x = 6 引爆[2,8] [1,6] 公共区间 [2,6]
// x = 11 引爆[7,12] [10,16] 公共区间即为[10,12]
// [10,12] 与 [2,6] 没有公共区间
// 那么更新公共区间 [第二个区间的左端点,pre]
// 在看上面的例子 更新的公共区间左端点都是第二个区间的左端点(小于第一个区间的右端点 说明交叉,作为左端点)
// 但是 对于右端点 有可能是第一个区间的右端点 有可能是第二个区间的右端点 选取最小的!
pre = min(pre,points[i][1]);
}
}
return res;
}
};