跳到主要内容

968.监控二叉树

链接:968.监控二叉树
难度:Hard
标签:树、深度优先搜索、动态规划、二叉树
简介:给定一个二叉树,我们在树的节点上安装摄像头。节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。计算监控树的所有节点所需的最小摄像头数量。

题解 1 - typescript

  • 编辑时间:2020-09-22
  • 执行用时:96ms
  • 内存消耗:43MB
  • 编程语言:typescript
  • 解法介绍:[参考连接](https://leetcode-cn.com/problems/binary-tree-cameras/solution/jian-kong-er-cha-shu-by-leetcode-solution/)。
function minCameraCover(root: TreeNode | null): number {
return dfs(root)[1];
/**
* @return
* 状态 a:root 必须放置摄像头的情况下,覆盖整棵树需要的摄像头数目。
* 状态 b:覆盖整棵树需要的摄像头数目,无论 root 是否放置摄像头。
* 状态 c:覆盖两棵子树需要的摄像头数目,无论节点 root 本身是否被监控到。
*/
function dfs(root: TreeNode | null): [number, number, number] {
if (root === null) return [Infinity, 0, 0];
const [la, lb, lc] = dfs(root.left);
const [ra, rb, rc] = dfs(root.right);
const a = lc + rc + 1;
return [a, Math.min(a, la + rb, ra + lb), Math.min(a, lb + rb)];
}
}

题解 2 - typescript

  • 编辑时间:2021-04-04
  • 执行用时:140ms
  • 内存消耗:48.4MB
  • 编程语言:typescript
  • 解法介绍:递归计算每个点的存在摄像头和父节点存在摄像头的情况。
/**
* dp[0][0] 父节点和当前节点都不存在摄像头
* dp[1][0] 父节点存在摄像头,当前节点不存在
* dp[0][1] 父节点不存在摄像头,当前节点存在
* dp[1][1] 父节点和当前节点都存在摄像头
*/
function minCameraCover(root: TreeNode | null): number {
const getArr = (): number[][] => new Array(2).fill(0).map(_ => new Array(2).fill(0));
const dp: number[][] = getArr();
const dfs = (node: TreeNode | null, dp: number[][]): void => {
if (!node) {
// 如果节点是null
dp[1][0] = dp[0][0] = 0;
dp[0][1] = dp[1][1] = Infinity; // null节点不存在摄像头
} else if (!node.left && !node.right) {
// 如果节点是叶子节点
dp[0][0] = Infinity; // 不存在此种情况,叶子节点和父节点必须有一个有摄像头
dp[1][1] = dp[0][1] = 1;
dp[1][0] = 0;
} else {
const left: number[][] = getArr();
const right: number[][] = getArr();
dfs(node.left, left);
dfs(node.right, right);
dp[0][0] = Math.min(
left[0][1] + right[0][0],
left[0][0] + right[0][1],
left[0][1] + right[0][1]
); // 如果父节点和当前节点都不存在摄像头,则子节点最少存在一个摄像头
dp[1][0] = Math.min(left[0][0] + right[0][0], dp[0][0]); // 如果父节点存在摄像头,当前节点不存在,则子节点可以存在任意情况
dp[1][1] = dp[0][1] =
1 +
Math.min(
left[1][0] + right[1][0],
left[1][1] + right[1][0],
left[1][0] + right[1][1],
left[1][1] + right[1][1]
); // 如果父节点不存在摄像头,当前节点存在,则子节点可存在任意情况,由于当前节点存在,则需增1
}
};
dfs(root, dp);
return Math.min(dp[0][1], dp[0][0]);
}