Skip to content

Minimum Number of Arrows to Burst Balloons

Given an array of events where events[i] = [start, end], find the minimum number of arrows needed to burst all balloons. Each arrow can burst balloons overlapping at any point.

InputOutputExplanation
[[10,16],[2,8],[1,6],[7,12]]2At position 8: burst [2,8], [1,6], [7,12]. At 16: burst [10,16].
[[1,2],[2,3],[3,4]]2At position 2: burst [1,2], [2,3]. At 4: burst [3,4].
[[1,2],[1,2],[1,2]]1One arrow at position 2 bursts all three.
[[9,12],[12,15],[16,20],[2,3],[1,6],[8,11]]2Optimal placement needed based on overlapping intervals.
  • 1 <= balloons.length <= 10^5
  • balloons[i].length == 2
  • -2^31 <= x_start < x_end <= 2^31 - 1
ApproachTimeSpaceNotes
Greedy Sort by EndO(n log n)O(1)Sort once, single pass—most intuitive
Sort by End (Variant)O(n log n)O(1)Identical to greedy, different framing
Section titled “Approach 1: Greedy Sort by End Position (Recommended)”
★ Recommended

Sort intervals by their end position, then use a greedy strategy: always shoot the next arrow at the position where the current interval ends. If the next interval starts after that position, it wasn’t hit, so shoot again.

This works because placing an arrow as far right as possible (at the end of the current interval) maximizes the chance of hitting future intervals.

⏱ Time O(n log n) Sorting dominates 💾 Space O(1) Only pointer variables

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

After sorting by end position: [[1,6],[2,8],[7,12],[10,16]]

StepCurrentLast ArrowHit?Action
1[1,6]--Shoot arrow at 6
2[2,8]6Yes6 ∈ [2,8], no new arrow
3[7,12]6No7 > 6, shoot arrow at 12
4[10,16]12Yes12 ∈ [10,16], no new arrow
Result:2 arrows
function minArrowShots(intervals):
if intervals is empty:
return 0
sort intervals by end position
arrows = 1
lastEnd = intervals[0].end
for each interval in intervals[1..n-1]:
if interval.start > lastEnd:
arrows += 1
lastEnd = interval.end
return arrows
burst_balloons_greedy.py
from typing import List
def findMinArrowShots(points: List[List[int]]) -> int:
"""Greedy approach: O(n log n) time, O(n) space"""
if not points:
return 0
points.sort(key=lambda x: x[1])
arrows = 1
last_end = points[0][1]
for start, end in points[1:]:
if start > last_end:
arrows += 1
last_end = end
return arrows
✓ Simple

An alternative framing: sort by end position, then iterate once. The algorithm is identical to Approach 1 but emphasizes the “sort once, scan once” structure.

⏱ Time O(n log n) Sort + single scan 💾 Space O(1) No extra data structures
function minArrowShots(intervals):
if empty:
return 0
sort by end position (ascending)
count = 1
lastArrowPos = intervals[0][1]
for i = 1 to n-1:
if intervals[i][0] > lastArrowPos:
count += 1
lastArrowPos = intervals[i][1]
return count
burst_balloons_sort.py
from typing import List
def findMinArrowShots(points: List[List[int]]) -> int:
"""Sort approach: O(n log n) time, O(n) space"""
if not points:
return 0
points.sort()
arrows = 1
last_end = points[0][1]
for start, end in points[1:]:
if start > last_end:
arrows += 1
last_end = end
return arrows
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
minimum_number_of_arrows_to_burst_balloons_space_optimized.py
"""
Solution for Minimum Number of Arrows to Burst Balloons
"""
def solve():
"""Implementation for approach 3 of Minimum Number of Arrows to Burst Balloons"""
pass
if __name__ == "__main__":
print("Solution ready")