给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
示例 1:
输入: [ [1,2], [2,3], [3,4], [1,3] ]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
示例 2:
输入: [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
示例 3:
输入: [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/non-overlapping-intervals
参考:
python
# 0435.无重叠区间
class Solution:
def eraseOverlapingIntervals(self, intervals:[[int]]) -> int:
"""
贪心算法,右边界排序,从左往右右边界尽量小,记录重叠的数量
:param intervals:
:return:
"""
if len(intervals) == 0: return 0
intervals.sort(key=lambda x: x[1]) # 按右边界排序
count = 1 # 非交叉区间shu
end = intervals[0][1] # 记录区间的分割点, max
for i in range(1, len(intervals)):
if end <= intervals[i][0]: # 非交叉区间,前区间的右边界<=当前区间的左边界
count += 1
end = intervals[i][1]
return len(intervals) - count # 去掉的重叠区间最少
if __name__ == "__main__":
test = Solution()
print(test.eraseOverlapingIntervals([ [1,2], [2,3], [3,4], [1,3] ]))
golang
package greedy
import "sort"
// 贪心算法,右边界升序排序
func eraseOverlapingIntervals1(intervals [][]int) int {
var count int
sort.Slice(intervals, func(i, j int) bool {
return intervals[i][1] < intervals[j][1]
})
end := intervals[0][1]
for i:=1;i<len(intervals);i++ {
if end <= intervals[i][0] { // 非交叉计数
count++
end = intervals[i][1]
}
}
return len(intervals)-count
}
// 贪心算法-左边界升序排序,比较前区间的右边界与当前区间的左边界
func eraseOverlapingIntervals(intervals [][]int) int {
var flag int
sort.Slice(intervals, func(i, j int) bool {
return intervals[i][0] < intervals[j][0]
})
for i:=1;i<len(intervals);i++ {
if intervals[i-1][1] > intervals[i][0] {
flag++
//由于是先排序的,所以,第一位是递增顺序,
//故只需要将临近两个元素的第二个值最小值更新到该元素的第二个值即可作之后的判断
intervals[i][1] = min(intervals[i-1][1], intervals[i][1])
}
}
return flag
}
func min(a,b int) int {
if a < b {
return a
}
return b
}