452. Minimum Number of Arrows to Burst Balloons

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 104 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进行排序,如果相同就按照结束的y进行排序,排序之后,可以尽可能的重合气球的行走路线,减少射箭的次数。

然后获取开始气球的结束坐标,遍历所有的气球,如果目标气球的开始坐标小于当前结束坐标,说明可以射击一次完成,如果开始坐标大于结束坐标,那么需要增加射击次数,并且重置当前结束坐标。同时需要注意的是,如果当前气球的开始坐标小于结束坐标,那么需要更新结束坐标为两个结束坐标中较小的那个。举例,【2,8】和【1,6】的重复区域是【2,6】,虽然【7,12】和【2,8】也有重复区域,但是和【1,6】没有,所以需要射击两次。

public class Solution {
    class Point {
		int x;
		int y;

		public Point(int i, int j) {
			x = i;
			y = j;
		}
	}
	
    public int findMinArrowShots(int[][] points) {
		if (points == null || points.length == 0)
			return 0;
		List<Point> pointList = new ArrayList<Point>();
		for (int i = 0; i < points.length; i++) {
			pointList.add(new Point(points[i][0], points[i][1]));
		}
		pointList.sort(new Comparator<Point>() {

			@Override
			public int compare(Point o1, Point o2) {
				if (o1.x == o2.x && o1.y < o2.y) {
					return -1;
				} else if (o1.x < o2.x) {
					return -1;
				}
				return 1;
			}
		});
		int end = pointList.get(0).y;
		int res = 1;
		for (int i = 1; i < pointList.size(); i++) {
			if (pointList.get(i).x <= end) {
				end = Math.min(end, pointList.get(i).y);
			} else {
				res++;
				end = pointList.get(i).y;
			}
		}
		return res;
    }
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值