452. Minimum Number of Arrows to Burst Balloons(Medium)

原题目:
  There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it’s horizontal, y-coordinates don’t matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 10^4 balloons.

  An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons.

Example:

Input:
[[10,16], [2,8], [1,6], [7,12]]

Output:
2

Explanation:
One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x = 11 (bursting the other two balloons).

题目大意如下:
  在二维平面上的有X轴上分布着一些气球,给出一些区间范围表示气球的大小,如:[10,16]表示一个气球正好充满了[10,16]这个区间。现在我们朝着y轴的方向射箭,箭一旦射出会一直按照y轴方向飞行(不会射到其他的气球),射箭的点可以是x轴上的任何一个点。现在求需要射爆所有气球所需要的最小的箭的个数。

解题思路:
  又是求最优解,所以我们还是从贪心算法开始着手。那么最优子结构如何分解呢(best move)?
  从题目可以得知,如果有两个区间重合,我们只需要射重合的那个地方就可以一下射爆多个气球,而当区间不重合的时候,我们就需要另外再射一支箭,所以我们需要看看有哪些区间是重合的。
  Key step:排序。(事实上很多greedy算法最开始都需要排序)
  我们先按照区间结束的点从小到大进行排序,这样的话我们只需要看后一个区间的起始位置是否在前一个区间的结束位置之前就能判断是否两个区间重合。先射一支箭,记录下射箭的postion,然后一直看后面的区间是否在这个射箭点内,如果在,就不需要再多射一支箭,如果没有,我们就得再射一支箭。

代码如下:

class Solution {
public:
    int findMinArrowShots(vector<pair<int, int>>& points) {
        int count = 0 , arrow = INT_MAX ;
        //按照区间结束点从小到大排序
        sort(points.begin() , points.end() , cmp );
        for(auto i : points){
            //如果后面的区间包含射箭点就不需要再射
            if(arrow != INT_MAX && i.first <= arrow) continue ;
            arrow = i.second ;
            count++ ;
        }
        return count ;
    }

    static bool cmp(pair<int, int>& a , pair<int, int>& b){
        if(a.second == b.second) return a.first<b.first ;
        return a.second<b.second ;
    }


};

运行结果:
运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值