解题思路: 因为叶子节点必定不要安装监视器,这样才能使总监视器数量比较少,所以须要从下往上进行判断当前节点的状态(共:3种状态):node
对于空节点,咱们认为是可观,但没有安装监视器,所以,叶子节点就为不可观的了,设想一个节点的左右孩子(为空)均可观且没有安装监视器,那该节点必然是不可观即2spa
有了以上对空节点和叶子节点的处理,咱们再来正式分析非终端节点:code
记住,咱们以上的分析都是基于从整个二叉树的叶子节点往根部,即从下往上进行,并且要作的就是将不可观的节点变得可观才行(所以要根据左右孩子的节点的状态来判断当前节点状态并作出调整)blog
这里可能会有疑惑,以上的第一条得出当前节点不可观,而后安装了监视器,而第三条也得出当前节点不可观,但却没有安装监视器,而是直接返回的2状态(当前节点不可观).这是为何?递归
由于,对于第一条,由于左右孩子都不可观,为了让左右孩子均可观,则必须给当前节点安装监视器才行,而第三条中,左右孩子都是可观的(没有安装监视器),当前节点的能够直接返回不可观状态,由于后面能够由他的父节点进行摄像头安装,使其变得可观.it
方法一:递归class
// 0:该节点安装了监视器 1:该节点可观,但没有安装监视器 2:该节点不可观 int monitor = 0; int state(TreeNode* node) { if (node == nullptr) return 1; int left = state(node->left); int right = state(node->right); // 该节点为0的状况 if (left == 2 || right == 2) { monitor++; // 因为左或右节点不可观,则须要给当前节点安装监视器,为0状态 return 0; } // 为1的状况 else if (left == 0 || right == 0) return 1; // 当(left!=2&&right!=2)时,才会进行该判断,也就是左右节点必定是可观的,再判断是否有一个安装了监视器,若有安装,则当前节点就不须要安装监视器也可观了,为1状态 // 为2的状况 else // 其余:党(left!=2&&right!=2)&&(left!=0&&right!=0),即left==1&&right==1时,左右节点均可观,但没有监视器,当前节点不可观,为2状态 return 2; } int minCameraCover(TreeNode *root) { if (root == nullptr) return 0; if (state(root) == 2) monitor++; // 若是根节点为2的状态,须要加一个监视器 return monitor; }
注意:这里的if,else if,else的顺序是不能变的,先判断左右都是不可观的,再就是均可观,左或右至少有一个为监视器,最后才是均可观都无监视器.二叉树