Binary Tree Cameras

hard binary tree dfs greedy

Problem

You are given the root of a binary tree. Install the minimum number of cameras on the tree nodes. Each camera at a node can monitor its parent, itself, and its immediate children. Return the minimum number of cameras needed to monitor all nodes of the tree.

Inputroot = [0, 0, null, 0, 0]
Output1
One camera placed on the lone middle node covers itself, its parent (the root), and its two children — the whole tree with a single camera.

NEED, CAM, OK = 0, 1, 2

def min_camera_cover(root):
    cameras = 0
    def dfs(node):
        nonlocal cameras
        if not node:
            return OK
        left = dfs(node.left)
        right = dfs(node.right)
        if left == NEED or right == NEED:
            cameras += 1
            return CAM
        if left == CAM or right == CAM:
            return OK
        return NEED
    if dfs(root) == NEED:
        cameras += 1
    return cameras
const NEED = 0, CAM = 1, OK = 2;

function minCameraCover(root) {
  let cameras = 0;
  function dfs(node) {
    if (!node) return OK;
    const left = dfs(node.left);
    const right = dfs(node.right);
    if (left === NEED || right === NEED) {
      cameras++;
      return CAM;
    }
    if (left === CAM || right === CAM) return OK;
    return NEED;
  }
  if (dfs(root) === NEED) cameras++;
  return cameras;
}
class Solution {
    static final int NEED = 0, CAM = 1, OK = 2;
    int cameras = 0;

    public int minCameraCover(TreeNode root) {
        if (dfs(root) == NEED) cameras++;
        return cameras;
    }

    private int dfs(TreeNode node) {
        if (node == null) return OK;
        int left = dfs(node.left);
        int right = dfs(node.right);
        if (left == NEED || right == NEED) {
            cameras++;
            return CAM;
        }
        if (left == CAM || right == CAM) return OK;
        return NEED;
    }
}
class Solution {
    static const int NEED = 0, CAM = 1, OK = 2;
    int cameras = 0;

    int dfs(TreeNode* node) {
        if (!node) return OK;
        int left = dfs(node->left);
        int right = dfs(node->right);
        if (left == NEED || right == NEED) {
            cameras++;
            return CAM;
        }
        if (left == CAM || right == CAM) return OK;
        return NEED;
    }
public:
    int minCameraCover(TreeNode* root) {
        if (dfs(root) == NEED) cameras++;
        return cameras;
    }
};
Time: O(n) Space: O(h)