LeetCode 968.BinaryTreeCameras 监控二叉树

题目链接

LC.968

题解

题意

emm如题啦~

思路

我们将“覆盖”定义为该节点可以被监控到。
设节点有三种状态:

  1. 未被覆盖;
  2. 有摄像头;
  3. 已被覆盖。

为了使用最少的摄像头,监控尽可能多的节点,我们要自下而上地安装摄像头。
为了完成这个操作,我们需要用到后序遍历。

关于返回的状态,我们从叶子节点的子节点——空节点开始推导。
对于一个空节点:

  1. 如果它的状态为未被覆盖,则其父节点处需要安装摄像头,造成浪费;
  2. 如果它的状态为有摄像头,则其父节点处状态为已被覆盖,导致摄像头安装在其父节点的父节点(爷爷节点喽~)的父节点处,造成其父节点——叶子节点无法被覆盖;
  3. 如果它的状态为已被覆盖,则其父节点处状态为未被覆盖,使得摄像头安装在其父节点的父节点处,完美~

最后需要处理一下根节点,如果返回状态为未被覆盖,则最终的结果需要加1。

AC代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
    
public:
    int ans = 0;

    int dfs(TreeNode* root) {
    
    
        if (root == nullptr) {
    
    
            return 2;
        }
        int left = dfs(root->left);
        int right = dfs(root->right);

        // 如果有子节点未被覆盖,则需要安摄像头
        if ((left == 0 && right == 0) || (left == 1 && right == 0) || (left == 0 && right == 1) || (left == 0 && right == 2) || (left == 2 && right == 0)) {
    
    
            ans += 1;
            return 1;
        }
        // 如果子节点可以覆盖此处,则返回已覆盖
        if ((left == 1 && right == 2) || (left == 2 && right == 1) || (left == 1 && right == 1)) {
    
    
            return 2;
        }
        // 如果子节点已被覆盖,则此处无需摄像头且未被覆盖
        if ((left == 2 && right == 2)) {
    
    
            return 0;
        }
        return 0;
    }

    int minCameraCover(TreeNode* root) {
    
    
        if (dfs(root) == 0) {
    
    
            ans += 1;
        }
        return ans;
    }
};

后记

啊这是我之前wa了两次的代码,我推啊推的觉得没问题,甚至十分完美,发现错在哪的我宛如智障QAQ
(不过我可以蹲一个只监控子节点的题hhhhhhhhhh

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
    
    
public:
    int ans = 0;

    bool dfs(TreeNode *root) {
    
    
        while (root->left != nullptr || root->right != nullptr) {
    
    
            bool son1 = false, son2 = false;
            if (root->left == nullptr || (root->left->left == nullptr && root->left->right == nullptr)) {
    
    
                son1 = true;
            } else {
    
    
                if (dfs(root->left)) root->left = nullptr;
            }
            if (root->right == nullptr || (root->right->right == nullptr && root->right->left == nullptr)) {
    
    
                son2 = true;
            } else {
    
    
                if (dfs(root->right)) root->right = nullptr;
            }
            if (son1 && son2) {
    
    
                ans += 1;
                return true;
            }
        }
        return false;
    }
    
    int minCameraCover(TreeNode* root) {
    
    
        if (root -> left == nullptr && root -> right == nullptr) return 1;
        else if (root == nullptr) return 0;
        dfs(root);
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_45934120/article/details/108739932