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:
//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;
} |
/*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));
}
} |
# 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))
|
//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));
}
} |
// 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)); |
9
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