题目三:
思路
大家应该都感觉到了,此题一定要排序,那么按照左边界排序,还是右边界排序呢?
都可以!
那么我按照左边界排序,排序之后局部最优:每次合并都取最大的右边界,这样就可以合并更多的区间了,整体最优:合并所有重叠的区间。
局部最优可以推出全局最优,找不出反例,试试贪心。
那有同学问了,本来不就应该合并最大右边界么,这和贪心有啥关系?
有时候贪心就是常识!哈哈
按照左边界从小到大排序之后,如果 intervals[i][0] < intervals[i - 1][1] 即intervals[i]左边界 < intervals[i - 1]右边界,则一定有重复,因为intervals[i]的左边界一定是大于等于intervals[i - 1]的左边界。
即:intervals[i]的左边界在intervals[i - 1]左边界和右边界的范围内,那么一定有重复!
这么说有点抽象,看图:(注意图中区间都是按照左边界排序之后了)
知道如何判断重复之后,剩下的就是合并了,如何去模拟合并区间呢?
其实就是用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。
代码如下:
var merge = function(intervals) {
intervals.sort((a, b) => {
if (a[0] != b[0]) {
return a[0] - b[0]
} else {
return a[1] - b[1]
}
})
let pre = intervals[0]
let result = []
for (let i = 1; i < intervals.length; i++) {
console.log(pre)
let cur = intervals[i]
if (cur[0] > pre[1]) { // 不相交
result.push(pre)
pre = cur
} else { // 相交
pre[1] = Math.max(cur[1], pre[1])
}
}
result.push(pre)
return result
};