vlambda博客
学习文章列表

2021-08-05:监控二叉树。给定一个二叉树,我们在树的节点上安装摄像头。节点上的每个摄影头都可以监视其父对象、自身及其直接

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 = 0const COVERED_NO_CAMERA = 1const 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}}

执行结果如下:

***

[左神java代码](https://github.com/algorithmzuo/coding-for-great-offer/blob/main/src/class07/Code02_MinCameraCover.java)