2021-08-05:监控二叉树。给定一个二叉树,我们在树的节点上安装摄像头。节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。计算监控树的所有节点所需的最小摄像头数量。
福大大 答案2021-08-05:
1.递归。
X无相机,但X被覆盖。X下都被覆盖。
X有相机,但X被覆盖,X下都被覆盖。
X无相机,但X没被覆盖。X下都被覆盖。
2.贪心。
时间复杂度: O(N)。
空间复杂度: O(N)。
代码用golang编写。代码如下:
package main import "fmt" func main() { root := &TreeNode{value: 1} root.left = &TreeNode{value: 2} root.right = &TreeNode{value: 3} root.left.left = &TreeNode{value: 4} ret := minCameraCover2(root) fmt.Println(ret) } func minCameraCover2(root *TreeNode) int { data := process2(root) return data.cameras + twoSelectOne(data.status == UNCOVERED, 1, 0) } func twoSelectOne(c bool, a int, b int) int { if c { return a } else { return b } } type TreeNode struct { value int left *TreeNode right *TreeNode } type Status int const UNCOVERED = 0 const COVERED_NO_CAMERA = 1 const COVERED_HAS_CAMERA = 2 // 以x为头,x下方的节点都是被covered,得到的最优解中: // x是什么状态,在这种状态下,需要至少几个相机 type Data struct { status Status cameras int } func process2(X *TreeNode) *Data { if X == nil { return &Data{COVERED_NO_CAMERA, 0} } left := process2(X.left) right := process2(X.right) cameras := left.cameras + right.cameras // 左、或右,哪怕有一个没覆盖 if left.status == UNCOVERED || right.status == UNCOVERED { return &Data{COVERED_HAS_CAMERA, cameras + 1} } // 左右孩子,不存在没被覆盖的情况 if left.status == COVERED_HAS_CAMERA || right.status == COVERED_HAS_CAMERA { return &Data{COVERED_NO_CAMERA, cameras} } // 左右孩子,不存在没被覆盖的情况,也都没有相机 return &Data{UNCOVERED, cameras} }
执行结果如下: