Maximizing Robbery in Binary Tree Houses without Alerting Police
Last Updated :
18 Dec, 2023
There are Houses arranged in the form of a Binary tree. There is only one entrance to the houses which is the root of a tree. It will automatically contact the police if two directly linked houses are broken into on the same night. Given the root of the binary tree, return the maximum amount of money the thief can rob without alerting the police.
Examples:
Input: root = [3, 4, 5, 1, 3, null, 1]
3
/ \
4 5
/ \ \
1 3 1
Output: 9
Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.
Input: root = [3, 2, 3, null, 3, null, 1]
3
/ \
2 3
\ \
3 1
Output: 7
Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
Approach: To solve the problem follow the below steps:
- We will start from the root of tree and recursively check whether we can take the current node or not,
- If we take the current node then we will not be able to take the childs of the node we have to check if the grandchildrens exists or not
- Then we decide whether to pick them or not, We will do this recursively from the root to leaves of the tree and store the maximum amount that the robber can rob till that node and
- Modify the value of that node since we can encounter the same node in future we will mark it via using a dp set which ensures that we does not visit that node again and
- Like this we start updating the node value with the maximum amount that robber can rob at that node level and
- We update the tree in bottom-up fashion from leaves to the root and when we update the root value it contains the desired result that the maximum amount robber can rob if it starts from the root.
Below is the implementation of above approach:
C++
//code by Flutterfly
#include <iostream>
#include <deque>
#include <unordered_set>
#include <vector> // Add this line for vector support
using namespace std;
// 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:
// Function to find the maximum amount of money that can be robbed
int rob(TreeNode* root) {
unordered_set<TreeNode*> dp; // A set to store already calculated results for each node
return robb(root, dp); // Call the recursive function
}
private:
// Recursive helper function to calculate the maximum amount of money that can be robbed
int robb(TreeNode* root, unordered_set<TreeNode*>& dp) {
if (root == nullptr) {
return 0;
}
if (dp.find(root) != dp.end()) {
return root->val; // Return the previously calculated result if available
}
int notPick = 0;
int pick = 0;
int left = 0;
int right = 0;
if (root->left) {
left = robb(root->left->left, dp) + robb(root->left->right, dp);
}
if (root->right) {
right = robb(root->right->left, dp) + robb(root->right->right, dp);
}
pick = root->val + left + right;
notPick = robb(root->left, dp) + robb(root->right, dp);
root->val = max(pick, notPick); // Update the value of the current node
dp.insert(root); // Add the current node to the set to store the result
return root->val;
}
};
// Function to build a binary tree from a given string representation
TreeNode* buildTree(string s) {
if (s.empty() || s[0] == 'N') {
return nullptr;
}
vector<string> ip;
size_t pos = 0;
while ((pos = s.find(' ')) != string::npos) {
ip.push_back(s.substr(0, pos));
s.erase(0, pos + 1);
}
ip.push_back(s);
TreeNode* root = new TreeNode(stoi(ip[0])); // Create the root of the tree
size_t size = 0;
deque<TreeNode*> q;
q.push_back(root);
size++;
size_t i = 1;
while (size > 0 && i < ip.size()) {
TreeNode* currNode = q.front();
q.pop_front();
size--;
string currVal = ip[i];
if (currVal != "N") {
currNode->left = new TreeNode(stoi(currVal));
q.push_back(currNode->left);
size++;
}
i++;
if (i >= ip.size()) {
break;
}
currVal = ip[i];
if (currVal != "N") {
currNode->right = new TreeNode(stoi(currVal));
q.push_back(currNode->right);
size++;
}
i++;
}
return root;
}
int main() {
string s = "3 4 5 1 3 N 1";
TreeNode* root = buildTree(s);
Solution ob;
cout << ob.rob(root) << endl; // Print the result
return 0;
}
Java
/*code by Flutterfly */
import java.util.ArrayDeque;
import java.util.HashSet;
import java.util.Queue;
import java.util.Set;
// Definition for a binary tree node.
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
left = null;
right = null;
}
}
class Solution {
public int rob(TreeNode root) {
Set<TreeNode> dp = new HashSet<>();
return robb(root, dp);
}
private int robb(TreeNode root, Set<TreeNode> dp) {
if (root == null) {
return 0;
}
if (dp.contains(root)) {
return root.val;
}
int notPick = 0;
int pick = 0;
int left = 0;
int right = 0;
if (root.left != null) {
left = robb(root.left.left, dp) + robb(root.left.right, dp);
}
if (root.right != null) {
right = robb(root.right.left, dp) + robb(root.right.right, dp);
}
pick = root.val + left + right;
notPick = robb(root.left, dp) + robb(root.right, dp);
root.val = Math.max(pick, notPick);
dp.add(root);
return root.val;
}
}
public class Main {
public static TreeNode buildTree(String s) {
// Corner Case
if (s.length() == 0 || s.charAt(0) == 'N') {
return null;
}
// Creating list of strings from input string after splitting by space
String[] ip = s.split("\\s+");
// Create the root of the tree
TreeNode root = new TreeNode(Integer.parseInt(ip[0]));
int size = 0;
Queue<TreeNode> q = new ArrayDeque<>();
// Push the root to the queue
q.offer(root);
size++;
// Starting from the second element
int i = 1;
while (size > 0 && i < ip.length) {
// Get and remove the front of the queue
TreeNode currNode = q.poll();
size--;
// Get the current node's value from the string
String currVal = ip[i];
// If the left child is not null
if (!currVal.equals("N")) {
// Create the left child for the current node
currNode.left = new TreeNode(Integer.parseInt(currVal));
// Push it to the queue
q.offer(currNode.left);
size++;
}
// For the right child
i = i + 1;
if (i >= ip.length) {
break;
}
currVal = ip[i];
// If the right child is not null
if (!currVal.equals("N")) {
// Create the right child for the current node
currNode.right = new TreeNode(Integer.parseInt(currVal));
// Push it to the queue
q.offer(currNode.right);
size++;
}
i = i + 1;
}
return root;
}
public static void main(String[] args) {
String s = "3 4 5 1 3 N 1";
TreeNode root = buildTree(s);
Solution ob = new Solution();
System.out.println(ob.rob(root));
}
}
Python3
# Definition for a binary tree node.
# class Node:
# def __init__(self, val):
# self.val = val
# self.left = left
# self.right = right
from collections import deque
class Solution:
def rob(self, root):
def robb(root):
if root == None:
return 0
if root in dp:
return root.val
notPick = pick = 0
left = right = 0
if root.left:
left = robb(root.left.left) + robb(root.left.right)
if root.right:
right = robb(root.right.left) + robb(root.right.right)
pick = root.val + left + right
notPick = robb(root.left) + robb(root.right)
root.val = max(pick, notPick)
dp.add(root)
return root.val
dp = set()
return robb(root)
class Node:
def __init__(self, val):
self.left = None
self.val = val
self.right = None
def buildTree(s):
# Corner Case
if(len(s) == 0 or s[0] == "N"):
return None
# Creating list of strings from input
# string after spliting by space
ip = list(map(str, s.split()))
# Create the root of the tree
root = Node(int(ip[0]))
size = 0
q = deque()
# Push the root to the queue
q.append(root)
size = size+1
# Starting from the second element
i = 1
while(size > 0 and i < len(ip)):
# Get and remove the front of the queue
currNode = q[0]
q.popleft()
size = size-1
# Get the current node's value
# from the string
currVal = ip[i]
# If the left child is not null
if(currVal != "N"):
# Create the left child for
# the current node
currNode.left = Node(int(currVal))
# Push it to the queue
q.append(currNode.left)
size = size+1
# For the right child
i = i+1
if(i >= len(ip)):
break
currVal = ip[i]
# If the right child is not null
if(currVal != "N"):
# Create the right child for
# the current node
currNode.right = Node(int(currVal))
# Push it to the queue
q.append(currNode.right)
size = size+1
i = i+1
return root
s = '3 4 5 1 3 N 1'
root = buildTree(s)
ob = Solution()
print(ob.rob(root))
C#
//code by Flutterfly
using System;
using System.Collections.Generic;
// Definition for a binary tree node.
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) {
val = x;
left = null;
right = null;
}
}
public class Solution {
public int Rob(TreeNode root) {
HashSet<TreeNode> dp = new HashSet<TreeNode>();
return Robb(root, dp);
}
private int Robb(TreeNode root, HashSet<TreeNode> dp) {
if (root == null) {
return 0;
}
if (dp.Contains(root)) {
return root.val;
}
int notPick = 0;
int pick = 0;
int left = 0;
int right = 0;
if (root.left != null) {
left = Robb(root.left.left, dp) + Robb(root.left.right, dp);
}
if (root.right != null) {
right = Robb(root.right.left, dp) + Robb(root.right.right, dp);
}
pick = root.val + left + right;
notPick = Robb(root.left, dp) + Robb(root.right, dp);
root.val = Math.Max(pick, notPick);
dp.Add(root);
return root.val;
}
}
public class Program {
public static TreeNode BuildTree(string s) {
// Corner Case
if (string.IsNullOrEmpty(s) || s[0] == 'N') {
return null;
}
// Creating list of strings from input string after splitting by space
string[] ip = s.Split(' ');
// Create the root of the tree
TreeNode root = new TreeNode(int.Parse(ip[0]));
int size = 0;
Queue<TreeNode> q = new Queue<TreeNode>();
// Push the root to the queue
q.Enqueue(root);
size++;
// Starting from the second element
int i = 1;
while (size > 0 && i < ip.Length) {
// Get and remove the front of the queue
TreeNode currNode = q.Dequeue();
size--;
// Get the current node's value from the string
string currVal = ip[i];
// If the left child is not null
if (currVal != "N") {
// Create the left child for the current node
currNode.left = new TreeNode(int.Parse(currVal));
// Push it to the queue
q.Enqueue(currNode.left);
size++;
}
// For the right child
i = i + 1;
if (i >= ip.Length) {
break;
}
currVal = ip[i];
// If the right child is not null
if (currVal != "N") {
// Create the right child for the current node
currNode.right = new TreeNode(int.Parse(currVal));
// Push it to the queue
q.Enqueue(currNode.right);
size++;
}
i = i + 1;
}
return root;
}
public static void Main() {
string s = "3 4 5 1 3 N 1";
TreeNode root = BuildTree(s);
Solution ob = new Solution();
Console.WriteLine(ob.Rob(root));
}
}
JavaScript
// Definition for a binary tree node.
class TreeNode {
constructor(val) {
this.val = val;
this.left = null;
this.right = null;
}
}
class Solution {
rob(root) {
const dp = new Set();
function robHelper(node) {
if (!node) return 0;
if (dp.has(node)) return node.val;
let notPick = 0;
let pick = 0;
let left = 0;
let right = 0;
if (node.left) {
left = robHelper(node.left.left) + robHelper(node.left.right);
}
if (node.right) {
right = robHelper(node.right.left) + robHelper(node.right.right);
}
pick = node.val + left + right;
notPick = robHelper(node.left) + robHelper(node.right);
node.val = Math.max(pick, notPick);
dp.add(node);
return node.val;
}
return robHelper(root);
}
}
function buildTree(s) {
// Corner Case
if (s.length === 0 || s[0] === 'N') return null;
// Creating list of strings from input
// string after spliting by space
const ip = s.split(' ');
// Create the root of the tree
const root = new TreeNode(parseInt(ip[0]));
let size = 0;
const q = [];
// Push the root to the queue
q.push(root);
size++;
// Starting from the second element
let i = 1;
while (size > 0 && i < ip.length) {
// Get and remove the front of the queue
const currNode = q[0];
q.shift();
size--;
// Get the current node's value
// from the string
let currVal = ip[i];
// if the left child is not null
if (currVal !== 'N') {
// Create the left child for
// the current node
currNode.left = new TreeNode(parseInt(currVal));
// Push it to the queue
q.push(currNode.left);
size++;
}
// For the right child
i++;
if (i >= ip.length) break;
currVal = ip[i];
// If the right child is not null
if (currVal !== 'N') {
// Create the right child for
// the current node
currNode.right = new TreeNode(parseInt(currVal));
// Push it to the queue
q.push(currNode.right);
size++;
}
i++;
}
return root;
}
const s = '3 4 5 1 3 N 1';
const root = buildTree(s);
const ob = new Solution();
console.log(ob.rob(root));
Time Complexity: O(N) Since we are traversing the whole tree and there are total N nodes in the tree
Auxiliary Space: O(N) to store the answers in dp and the recursion stack space
Similar Reads
Maximizing Safety in a Robber-Infested Grid Given a 2D matrix grid of size n x n, where each cell contains either a robber (denoted by 1), is empty (denoted by 0), or an obstacle (denoted by -1). Your starting position is at cell (0, 0), and you can move to any adjacent cell in the grid, including cells containing robbers but you cannot move
15+ min read
House Robber - Maximum possible stolen value There are n houses built in a line, each of which contains some money in it. A robber wants to steal money from these houses, but he canât steal from two adjacent houses. The task is to find the maximum amount of money which can be stolen.Examples: Input: hval[] = {6, 7, 1, 3, 8, 2, 4}Output: 19Expl
15+ min read
Maximum number in Binary tree of binary values Given a binary tree consisting of nodes, each containing a binary value of either 0 or 1, the task is to find the maximum decimal number that can be formed by traversing from the root to a leaf node. The maximum number is achieved by concatenating the binary values along the path from the root to a
6 min read
Maximize the money when no two adjacent Array indices can be chosen Given an array of size N, each index has K amount of money, the target is to pick the maximum amount of money from the array but the constraint is that no two adjacent indices can be chosen. Examples: Input: N = 5, K = 10Output: 30Explanation: The possible option is to pick from the first, third and
3 min read
Shortest path for a thief to reach the Nth house avoiding policemen Given an unweighted graph and a boolean array A[ ], where if the ith index of array A[ ] denotes if that node can be visited (0) or not (1). The task is to find the shortest path to reach (N - 1)th node from the 0th node. If it is not possible to reach, print -1. Examples : Input : N = 5, A[] = {0,
11 min read