Solution For Minimum Number Of Arrows To Burst Balloons
Problem Statement:
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. The start is always smaller than the end.
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 traveling up infinitely.
Given an array points where points[i] = [xstart, xend], return the minimum number of arrows that must be shot to burst all balloons.
Solution:
Let’s begin with simple Greedy Algorithm – We can choose the balloon with the smallest end coordinate. In this way, we can always shoot one arrow to burst the balloons that have common end. We repeat this process until the no balloons left. In this way we will calculate minimum number of arrows to burst balloons. Let’s implement this approach.
Algorithm:
- Sort the balloons in ascending order based on the end coordinates.
- Set the end of the first balloon to be the end of the previous balloon.
- If the current balloon starts before the previous end, then it overlaps with the previous balloon and we don’t need to shoot another arrow for it. Update the end to be the minimum of the two ends.
- If the current balloon starts after the previous balloon, then we need to shoot another arrow and update the end to be the end of the current balloon.
- Return the number of arrows used.
Here is the implementation in Python:
“`
def findMinArrowShots(points):
if len(points) == 0:
return 0
# sort the balloons by end coordinate
points.sort(key = lambda x: x[1])
# initialize variables
arrows = 1
end = points[0][1]
# iterate through the balloons
for i in range(1, len(points)):
# if it overlaps
if points[i][0] <= end:
end = min(end, points[i][1])
else:
# if it doesn't overlap
arrows += 1
end = points[i][1]
return arrows
“`
Time Complexity:
Sorting takes O(nlogn) and we iterate through the balloons once, therefore, the time complexity is O(nlogn).
Space Complexity:
We do not use any extra data structure, so the space complexity is O(1).
Note:
This approach is a greedy algorithm that finds the optimal solution at each step, so it is guaranteed to be the minimum.
This algorithm can be easily memorized as well.
Step by Step Implementation For Minimum Number Of Arrows To Burst Balloons
class Solution { public int findMinArrowShots(int[][] points) { if (points.length == 0) { return 0; } Arrays.sort(points, (a, b) -> a[1] - b[1]); int arrowPos = points[0][1]; int arrowCnt = 1; for (int i = 1; i < points.length; i++) { if (arrowPos >= points[i][0]) { continue; } arrowCnt++; arrowPos = points[i][1]; } return arrowCnt; } }
There may be multiple solutions to this problem, but we are only interested in the Python code. def findMinArrowShots(points): # Sort the points by x-coordinate (or by any other criteria) points.sort(key = lambda point: point[0]) # Initialize the minimum number of arrows to zero minArrowShots = 0 # Loop through the points for i in range(len(points)): # If this is the first point, we need at least one arrow to burst it if i == 0: minArrowShots += 1 # Otherwise, we check if this point can be burst by the previous point's arrow else: # If the x-coordinates of the two points are not equal, then we need another arrow if points[i][0] != points[i-1][0]: minArrowShots += 1 # If the x-coordinates are equal, we check the y-coordinates else: # If the y-coordinates are not equal, then we need another arrow if points[i][1] != points[i-1][1]: minArrowShots += 1 # If the x-coordinates and y-coordinates are equal, then we don't need another arrow return minArrowShots
var findMinArrowShots = function(points) { // sort points by x coordinate points.sort((a, b) => a[0] - b[0]); // arrow can only burst one balloon at a time // so start with first balloon and try to burst as many as possible with one arrow // then move on to next balloon let arrowCount = 0; let i = 0; while (i < points.length) { let start = points[i][0]; let end = points[i][1]; // move pointer to next balloon while current balloon can be burst by same arrow while (i < points.length - 1 && points[i + 1][0] <= end) { i++; end = Math.min(end, points[i][1]); } // arrow has been used, move on to next balloon arrowCount++; i++; } return arrowCount; };
There are a number of ways to solve this problem. One approach would be to sort the balloons by their x-coordinates (ascending order), and then start shooting the first balloon. For each balloon shot, check if there are any other balloons in its range. If so, shoot those balloons as well and continue checking. If there are no more balloons in range, move on to the next balloon. Another approach would be to keep track of the endpoints of the balloons (the leftmost and rightmost x-coordinates). Start by shooting the leftmost balloon. Then, check if the next balloon is in range. If so, shoot it and continue checking. If not, move on to the next balloon. Repeat until all balloons are shot.
using System; public class Solution { // Function to find the minimum number of // arrows required static int findMinArrowShots(int[][] points) { int n = points.Length; if (n == 0) return 0; // Sort the array by ending time Array.Sort(points, (a, b) => a[1].CompareTo(b[1])); // The idea is to shoot as many // overlapping balloons with one shot. int arrow = 1, i = 0; for (int j = 1; j < n; j++) { // Check if it is safe to shoot the // balloon with arrow shot at the // ending of previous balloon. if (points[i][1] < points[j][0]) { arrow++; i = j; } } return arrow; } // Driver Code public static void Main() { int[][] points = new int[][] { new int[] { 10, 16 }, new int[] { 2, 8 }, new int[] { 1, 6 }, new int[] { 7, 12 } }; Console.WriteLine(findMinArrowShots(points)); } }