Skip to content

无重叠区间-435 #90

@sl1673495

Description

@sl1673495

给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

注意:

可以认为区间的终点总是大于它的起点。
区间 [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 项中的最大值,也就是最长的非重叠区间长度,用区间的总长度减去这个最长长度,得出的就是需要移除掉的数组长度。

/**
 * @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)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    动态规划待复习看题解或者做出来很艰难的,需要回顾。

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy