将有序无重复整数数组按连续区间分组,每个区间表示为
"a"或"a->b"。
var summaryRanges = function(nums) {
const res = []
let i = 0
while (i < nums.length) {
// 当前区间的起点
const start = nums[i]
// 向右扩展:只要下一个数比当前大 1,就移动 i
while (i + 1 < nums.length && nums[i + 1] === nums[i] + 1)
i++
// i 停留在区间终点,根据长度决定输出格式
if (start === nums[i])
res.push(`${start}`)
else
res.push(`${start}->${nums[i]}`)
i++
}
return res
}合并所有重叠区间,返回不重叠的区间数组。
var merge = function(intervals) {
if (!intervals.length) return []
intervals.sort((a, b) => a[0] - b[0])
const res = [intervals[0]]
for (let i = 1; i < intervals.length; i++) {
let last = res[res.length - 1]
// 不重叠:当前区间起点 > 上一个终点
if (intervals[i][0] > last[1]) {
res.push(intervals[i])
}
// 重叠:扩展右端点(用条件判断代替 Math.max)
else if (last[1] < intervals[i][1]) {
last[1] = intervals[i][1]
}
}
return res
}在有序区间数组中插入一个新区间,合并所有重叠区间。O(n) 一次遍历完成。
var insert = function(intervals, newInterval) {
const res = []
let [c, d] = newInterval
let i = 0
// 阶段 1:左边不重叠的区间(当前区间终点 < newInterval 起点)
while (i < intervals.length && intervals[i][1] < c) {
res.push(intervals[i])
i++
}
// 阶段 2:合并所有重叠区间(当前区间起点 <= newInterval 终点)
while (i < intervals.length && intervals[i][0] <= d) {
c = Math.min(c, intervals[i][0])
d = Math.max(d, intervals[i][1])
i++
}
res.push([c, d])
// 阶段 3:剩余不重叠的区间直接加入
while (i < intervals.length) {
res.push(intervals[i])
i++
}
return res
}每支箭射在某个 x 位置,引爆
[start, end]包含 x 的所有气球。求最少需要几支箭。贪心:按右端点排序,在每个重叠区间的最右射箭,跳过所有被覆盖的气球。
var findMinArrowShots = function(points) {
// 按右端点升序:优先处理结束早的气球,给后面留更多空间
points.sort((a, b) => a[1] - b[1])
let arrows = 1
let i = 0
while (i < points.length) {
// 在当前气球右端射箭
const end = points[i][1]
i++
// 跳过所有能被这支箭射到的气球(起点 <= 箭位置)
while (i < points.length && points[i][0] <= end)
i++
// 还有气球没射到,需要再射一箭
if (i < points.length)
arrows++
}
return arrows
}