Open sl1673495 opened 4 years ago
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
[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 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
本题可以转化成最长上升子序列-300相同的问题。
先把区间数组按照每个数组的开头项排序,然后用 dp[i] 表示从 [0, i] 能构成的最长的无重叠区间的个数,利用上升子序列的同样思路去求解即可。对于每个区间intervals[i],都从 0 ~ j 去逐个遍历之前的项,一旦发现 i.start >= j.end 说明这两者构成非重叠区间,那么就把 max 值尝试更新为 dp[j] + 1。
dp[i]
intervals[i]
0 ~ j
i.start >= j.end
max
dp[j] + 1
最后找出所有 dp 项中的最大值,也就是最长的非重叠区间长度,用区间的总长度减去这个最长长度,得出的就是需要移除掉的数组长度。
/** * @param {number[][]} intervals * @return {number} */ let eraseOverlapIntervals = function (intervals) { let n = intervals.length if (!n) { return 0 } // 按照起始点排序 intervals.sort((a, b) => a[0] - b[0]) // dp[i] 表示从 [0, i] 能构成的最长的无重叠区间的个数 let dp = [] dp[0] = 1 for (let i = 1; i < n; i++) { let max = 1 let [curStart] = intervals[i] for (let j = 0; j < i; j++) { let [prevStart, prevEnd] = intervals[j] if (prevEnd <= curStart) { max = Math.max(max, dp[j] + 1) } } dp[i] = max } return n - Math.max(...dp) }
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。 区间
[1,2]
和[2,3]
的边界相互“接触”,但没有相互重叠。来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/non-overlapping-intervals 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
本题可以转化成最长上升子序列-300相同的问题。
先把区间数组按照每个数组的开头项排序,然后用
dp[i]
表示从 [0, i] 能构成的最长的无重叠区间的个数,利用上升子序列的同样思路去求解即可。对于每个区间intervals[i]
,都从0 ~ j
去逐个遍历之前的项,一旦发现i.start >= j.end
说明这两者构成非重叠区间,那么就把max
值尝试更新为dp[j] + 1
。最后找出所有 dp 项中的最大值,也就是最长的非重叠区间长度,用区间的总长度减去这个最长长度,得出的就是需要移除掉的数组长度。