Binary Tree Cameras Problem
Problem
You are given the root
of a binary tree. We install cameras on the tree nodes where 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.
Examples
Example 1:
Input:
root = [0,0,null,0,0]
Output:
1
Explanation: One camera is enough to monitor all nodes if placed as shown.
Example 2:
Input:
root = [0,0,null,0,null,0,null,null,0]
Output:
2
Explanation: At least two cameras are needed to monitor all nodes of the tree. The above image shows one of the valid configurations of camera placement.
Constraints:
- The number of nodes in the tree is in the range
[1, 1000]
. Node.val == 0
Solution
Method 1 - Post-order Traversal
We can cover the nodes with camera in these ways:
- A node in binary tree can be covered in 4 ways - by placing camera on - 1) itself, 2) parent, 3) left child, 4) right child.
- A root node can be covered in 3 ways - by placing camera on - 1) itself, 2) left child, 3) right child
- A leaf node can be covered in 2 ways - by placing camera on - 1) itself, 2) parent
Now, if we set a camera at the leaf (case 3), the camera can cover only leaf and its parent, but if we set a camera at its parent(case 1 or 2), the camera can cover the leaf, its parent and its sibling. In latter approach, we require less cameras to cover the nodes.
So, we can start placing cameras on the leaves parent and continue till all nodes are covered. As, we are taking decision based on children, we will do post-order traversal.
Algorithm
We can use enum MonitoringStatus
- where we have 3 statuses:
- Not Monitored yet
- Monitored without camera on it
- Monitored with camera on it
We start the dfs which returns MonitoringStatus
:
0. Initiate numCameras
to 0
- For leaf nodes, we will return
NotMonitored
- For parent node of leaf, we return
MonitoredWithCam
, and incrementnumCameras
. - For any other node, we return
MonitoredWithoutCam
Code
Java
class Solution {
// enum MonitoringStatus {
// NotMonitored, MonitoredWithoutCam, MonitoredWithCam
// }
private final int NotMonitored = 0;
private final int MonitoredWithoutCam = 1;
private final int MonitoredWithCam = 2;
private int numCameras = 0;
public int minCameraCover(TreeNode root) {
var monitoringStatus = dfs(root);
if (monitoringStatus == NotMonitored) {
numCameras++;
}
return numCameras;
}
private int dfs(TreeNode root) {
if (root == null) {
return MonitoredWithoutCam;
}
var left = dfs(root.left);
var right = dfs(root.right);
if (left == NotMonitored || right == NotMonitored) {
numCameras++;
return MonitoredWithCam;
}
if (left == MonitoredWithCam || right == MonitoredWithCam) {
return MonitoredWithoutCam;
}
return NotMonitored;
}
}
Complexity
- Time:
O(n)
- Space:
O(h) => O(n)
(assuming recursive stack)