[路飞]_leetcode_968. 监控二叉树

100 阅读1分钟

给定一个二叉树,我们在树的节点上安装摄像头。

节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。

计算监控树的所有节点所需的最小摄像头数量。

解题思路

设置一个递归函数 f(root) = dp[2][2]

dp[0][0]:父节点不放置,本节点不放置
dp[1][0]: 父节点放置,本节点不放置
dp[0][1]: 父节点不放置,本节点放置
dp[1][1]: 父节点放置,本节点放置

利用动态规划处理各种情况节点

  1. 空节点
  2. 叶子节点
  3. 其他节点

代码

var getDp = function (root) {
    let dp = [[10000, 10000], [10000, 10000]]
    // 处理空节点
    if (!root) {
        dp[0][0] = 0
        dp[1][0] = 0
        dp[0][1] = 10000 // 空节点:本节点放置是不行的
        dp[1][1] = 10000 // 空节点:本节点放置是不行的
        return dp
    }
    // 处理叶子节点
    if (!root.left && !root.right) {
        dp[0][0] = 10000 // 当前节点不放置,父节点也不放置,当前节点就无法覆盖,出错
        dp[1][0] = 0
        dp[0][1] = 1
        dp[1][1] = 1
        return dp
    }
    // 处理其他节点
    let l = getDp(root.left)
    let r = getDp(root.right)
    dp[0][0] = Math.min(Math.min(l[0][1] + r[0][0], l[0][0] + r[0][1]), l[0][1] + r[0][1])
    dp[1][0] = Math.min(dp[0][0], l[0][0] + r[0][0])
    dp[0][1] = Math.min(Math.min(l[1][0] + r[1][0], l[1][1] + r[1][1]), Math.min(l[1][1] + r[1][0], l[1][0] + r[1][1])) + 1
    dp[1][1] = dp[0][1]
    return dp
}
var minCameraCover = function(root) {
    let dp = getDp(root)
    return Math.min(dp[0][0], dp[0][1])
};