【力扣435. 无重叠区间】多种解法:贪心、dp(python3)
题目描述
https://leetcode-cn.com/problems/non-overlapping-intervals/
思路题解
方法1:贪心
本题可以转化为求不相交的区间个数。
贪心算法:
1. 按照区间的右端点从小到大排序
2. 每次都选择右端点最小的,不会出现重叠的区间,因为这样可以为后侧留下更多的选择空间
自己做的代码:
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
import functools
def cmp(a, b):
if b[1] < a[1]:
return 1
elif a[1] < b[1]:
return -1
else:
if b[0] < a[0]:
return -1
elif a[0] < b[0]:
return 1
else:
return 0
nums=sorted(intervals,key=functools.cmp_to_key(cmp))
i=0
ans=0
n=len(nums)
tmp=float("-inf")
while i<n:
while i<n and nums[i][0]<tmp:
# print(nums[i])
ans+=1
i+=1
if i<n:tmp=nums[i][1]
if i<n-1 and nums[i][1]==nums[i+1][1]:
j=i+1
tmp=nums[i][1]
while j<n and nums[j][1]==nums[i][1]:
# print(nums[j])
ans+=1
j+=1
i=j
else:
i+=1
return ans
方法2:dp
这道题可以使用动态规划做。本质上,这个题目和打家劫舍是一样的:
- 对于数组中的元素到底是选还是不选
对于此类问题,一般做法是dp[i]:代表一定选择当前元素时,最多的不重复区间个数。
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
n = len(intervals)
intervals.sort(key=lambda x:x[1])
#[[2,4],[3,4],[1,3],[0,3],[2,3]]
#变[[1, 3], [0, 3], [2, 3], [2, 4], [3, 4]]
right_end =intervals[0][1]
cnt = 1
for i in range(1, n):
# !!!! 这里的 >= 非常关键
if intervals[i][0] >= right_end:
cnt += 1
right_end =intervals[i][1]
return n - cnt