57.Insert Interval
Description:
You are given an array of non-overlapping intervals intervals where intervals[i] = [starti, endi] represent the start and the end of the ith interval and intervals is sorted in ascending order by starti. You are also given an interval newInterval = [start, end] that represents the start and end of another interval.
Insert newInterval into intervals such that intervals is still sorted in ascending order by starti and intervals still does not have any overlapping intervals (merge overlapping intervals if necessary).
Return intervals after the insertion.
Note that you don't need to modify intervals in-place. You can make a new array and return it.
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
Solution: Beat97.22%| Full explanation with pictures
As the intervals has already been sorted, we can divide the intervals list into three parts. The end of it is smaller than the start of newInterval, item overlaps newInterval, and The start of it is greater than the consolidated part.
fun insert(intervals: Array<IntArray>, newInterval: IntArray): Array<IntArray> {
val result = arrayListOf<IntArray>()
// traverse index
var i = 0
// Part1: the end of item is smaler than the start of newInterval
while (i < intervals.size && intervals[i][1] < newInterval[0]) {
result.add(intervals[i])
i++
}
// Part2: Partly overlap, extend the both end of the interval
while (i < intervals.size && intervals[i][0] <= newInterval[1]) {
newInterval[0] = min(newInterval[0], intervals[i][0])
newInterval[1] = max(newInterval[1], intervals[i][1])
i++
}
result.add(newInterval)
// Part3: The start of it is greater than the consolidated part.
while (i < intervals.size) {
result.add(intervals[i])
i++
}
return result.toTypedArray()
}
452.Minimum Number of Arrows to Burst Balloons
Description:
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] = [xstart, xend] denotes a balloon whose horizontal diameter stretches between xstart and xend. 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 xstart and xend is burst by an arrow shot at x if xstart <= x <= xend. 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.
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].
Solution: Easy 91.77% Beats
The problem asks for the minimum number of arrows needed to burst all balloons. Actually, it asks for finding non-overlapping intervals of balloons.
1.First, Sort the balloons; 2.Initialze the res = 1 and endPoint = points[0][1]; 3.Iterate the balloons; 4.Calculate the minimum arrows;
fun findMinArrowShots1(points: Array<IntArray>): Int {
// the end coordinates guarantee the left area is covered.
points.sortBy { it[1] }
var res = 1
var endPoint = points[0][1]
for (point in points) {
// point is big than current one, update he endPoint.
if (point[0] > endPoint) {
endPoint = point[1]
res++
}
}
return res
}
So, Could we sortBy it[0]? Absolutely yes. But we should look such situation: we have three balloons [0,9] [1,3] [4,7], if we just judge the point[0] and endPoint, then [0,9] will be the first, [1,3]'s point[0] < endPoint and do nothing, [4,7]'s point[0] < endPoint and do nothing. So it will get the wrong answer. Because [1,3] and [4,7] can't use just one arrow to brust them. The problem here is the first 9 can't guarantee the left area has been covered.
To get the right answer, When we deal with [0,9] and [1,3], we need to calculate the smallest covered area end coordinate 3.
fun findMinArrowShots(points: Array<IntArray>): Int {
points.sortBy { it[0] }
var res = 1
var endPoint = points[0][1]
for(point in points) {
if (point[0] > endPoint) {
endPoint = point[1]
res++
} else {
// find the smallest coordinate covering the left area.
endPoint = min(endPoint, point[1])
}
}
return res
}