There are some spherical balloons taped onto a flat wall that represents the XY-plane. The balloons are represented as a 2D integer array
points
where points[i] = [x
start
, x
end
]
denotes a balloon whose horizontal diameter stretches between x
start
and x
end
. You do not know the exact y-coordinates of the balloons.Arrows can be shot up directly vertically (in the positive y-direction) from different points along the x-axis. A balloon with
x
start
and x
end
is burst by an arrow shot at x
if x
start
<= x <= x
end
. There is no limit to the number of arrows that can be shot. A shot arrow keeps traveling up infinitely, bursting any balloons in its path.Given the array
points
, return the minimum number of arrows that must be shot to burst all balloons.Example 1:
Input: points = [[10,16],[2,8],[1,6],[7,12]] Output: 2 Explanation: The balloons can be burst by 2 arrows: - Shoot an arrow at x = 6, bursting the balloons [2,8] and [1,6]. - Shoot an arrow at x = 11, bursting the balloons [10,16] and [7,12].
Example 2:
Input: points = [[1,2],[3,4],[5,6],[7,8]] Output: 4 Explanation: One arrow needs to be shot for each balloon for a total of 4 arrows.
Example 3:
Input: points = [[1,2],[2,3],[3,4],[4,5]] Output: 2 Explanation: The balloons can be burst by 2 arrows: - Shoot an arrow at x = 2, bursting the balloons [1,2] and [2,3]. - Shoot an arrow at x = 4, bursting the balloons [3,4] and [4,5].
Constraints:
1 <= points.length <= 10
5
points[i].length == 2
2
31
<= x
start
< x
end
<= 2
31
- 1
풀이
재영
결국 우리가 자주 풀었던 문제의 유형이네요!
O(NlogN)
이면 거뜬하게 풀 수 있는 문제입니다. 😉
/** * @param {number[][]} points * @return {number} */ const findMinArrowShots = (points) => { points.sort(([a1], [b1]) => a1 - b1); let last = Infinity; let result = 0; points.forEach(([start, end]) => { if (last >= start) { if (!isFinite(last)) result += 1; last = Math.min(last, end); } else { result += 1; last = end; } }); return result; };
최적화 아닌 최적화…?
결과적으로 무한대인지에 대한 확인을
last >= start
일 때마다 하고 있습니다.이때,
points
는 무조건 1보다 크거나 같다는 조건이 있기 때문에, 항상 result
는 저 분기처리가 없을 때 1만큼 크다는 결과를 가질 수 있습니다. (첫 번째 터뜨려야 할 지점이 현재는 값에서 생략됐기 때문)따라서 결과 값에 1을 더하면 (무의미할 정도지만) 더 빠른 계산이 가능하겠군요!

/** * @param {number[][]} points * @return {number} */ const findMinArrowShots = (points) => { points.sort(([a1], [b1]) => a1 - b1); let last = Infinity; let result = 0; points.forEach(([start, end]) => { if (last >= start) { last = Math.min(last, end); } else { result += 1; last = end; } }); return result + 1; };
효성
/** * @param {number[][]} points * @return {number} */ var findMinArrowShots = function (points) { points.sort((a, b) => a[0] - b[0]); let prev = null; let count = 0; for (const [start, end] of points) { if (prev === null || prev < start) { count++; prev = end; } else { prev = Math.min(prev, end); }; } return count; };