Burning Tree | Practice | GeeksforGeeks

Given a binary tree and a node called target. Find the minimum time required to burn the complete binary tree if the target is set on fire. It is known that in 1 second all nodes connected to a given node get burned. That is its left child, right child, and parent.

Example 1:
Input:      
          1
        /   \
      2      3
    /  \      \
   4    5      6
       / \      \
      7   8      9
                   \
                   10
Target Node = 8
Output: 7
Explanation: If leaf with the value 
8 is set on fire. 
After 1 sec: 5 is set on fire.
After 2 sec: 2, 7 are set to fire.
After 3 sec: 4, 1 are set to fire.
After 4 sec: 3 is set to fire.
After 5 sec: 6 is set to fire.
After 6 sec: 9 is set to fire.
After 7 sec: 10 is set to fire.
It takes 7s to burn the complete tree.

Example 2:
Input:      
          1
        /   \
      2      3
    /  \      \
   4    5      7
  /    / 
 8    10
Target Node = 10
Output: 5


Your Task:  
You don't need to read input or print anything. Complete the function minTime() which takes the root of the tree and target as input parameters and returns the minimum time required to burn the complete binary tree if the target is set on fire at the 0th second.

Expected Time Complexity: O(N)
Expected Auxiliary Space: O(height of tree)

Constraints:
1 ≤ N ≤ 104
0
archit232002 days ago
Simple Java Solution based on Striver's Approach:-
 
public static int minTime(Node root, int target) {
            // Your code goes here
            calcParent(root, target);
            Queue<Node> q = new LinkedList<>();
            Map<Node, Boolean> visited = new LinkedHashMap<>();
            q.offer(n);
            int time = 0; //Only difference between the "Print nodes at a distance k from target" and this is that here we take the variable as time.
            while (q.isEmpty() == false) {
                int size = q.size();
                time++;
                for (int i = 0; i < size; i++) {
                    Node node = q.poll();
                    if (node.left != null && visited.get(node.left) == null) {
                        q.offer(node.left);
                        visited.put(node.left, true);
                    }
                    if (node.right != null && visited.get(node.right) == null) {
                        q.offer(node.right);
                        visited.put(node.right, true);
                    }
                    if (p.containsKey(node) == true && visited.get(p.get(node)) == null) {
                        q.offer(p.get(node));
                        visited.put(p.get(node), true);
                    }
                }
            }
            return time - 1;//We return time-1 as 1 sec extra time is counted due to the target node being processed first in the Queue
        }
0
satyamtiwari20163 weeks ago
    int minTime(Node* root, int target) 
    {
        // Your code goes here
        
        //parents map formation
        map<Node*,Node*> parent;
        parent[root]=NULL;
        Node* curr=NULL;
        queue<Node*> q;
        
        q.push(root);
        
        while(!q.empty()){
            
            Node* front = q.front();
            q.pop();
            
            
            if(front->data==target){
                curr=front;
            }
            
            if(front->left){
            q.push(front->left);
            parent[front->left]=front;
            }
            
            
            if(front->right){
            q.push(front->right);
            parent[front->right]=front;
            }
            
        }
        
        //parent map completed
        
        
        int time=0;
        
        
        map<Node*,bool> visited;
        queue<Node*> q1;
        q1.push(curr);
        
        visited[curr]=true;
        
        
        
        while(!q1.empty()){
            
            int size=q1.size();
            bool flag=false;
            
            for(int i=0;i<size;i++){
            
            Node* front=q1.front();
            q1.pop();
            
            
            if(parent[front] && !visited[parent[front]]){
            visited[parent[front]]=true;
            q1.push(parent[front]);
            flag=true;
            }
            
            
            if(front->left && !visited[front->left]){
            visited[front->left]=true;
            q1.push(front->left);
            flag=true;
            }
            
            if(front->right && !visited[front->right]){
            visited[front->right]=true;
            q1.push(front->right);
            flag=true;
            }
            
            }
            
            
            if(flag){
                time++;
            }
        }
        
        return time;
    }
0
adil033204 weeks ago
class Solution {
 public:
   void path (Node*root,int target,vector<Node*>temp,vector<Node*>&v){
       if(root==NULL) return;
       if(root->data==target){
           temp.push_back(root);
           v=temp;
           return;
       }
       temp.push_back(root);
       path(root->left,target,temp,v);
       path(root->right,target,temp,v);
   }
   int maxdis(Node*root,Node*bloc){
       if(root==NULL) return -1;
       if(root->data==bloc->data) return -1;
       int l=maxdis(root->left,bloc);
       int r=maxdis(root->right,bloc);
       return max(l,r)+1;
       // if(root->left==NULL && root->right==NULL) return 0;
       
   }
   int minTime(Node* root, int target) 
   {
       vector<Node*>v;
       vector<Node*>temp;
       path(root,target,temp,v);
       int maxi=INT_MIN;
       for(int i=v.size()-1;i>=0;i--){
           if(i==v.size()-1){
               Node*tt=new Node(-999999);
               maxi=max(maxi,maxdis(v[i],tt));
           }
           else{
               int dis=maxdis(v[i],v[i+1])+(v.size()-i-1);
               maxi=max(maxi,dis);
           }
       }
       // Your code goes here
       return maxi;
       
   }
};
+1
vipuldawar4 weeks ago
 
BFS approach:Steps:1) Find targetNode and Map for child to parent.2) BFS start with targetNode and keep checking for non-visited left, right or parent of currentNode and add it to q.
3) Keep increasing the time, if any node is burnt in any iteration.
 
 
public static int minTime(Node root, int target) {    // Your code goes here    Map<Node, Node> map = new HashMap<>();    Node[] targetNode = new Node[1];    fill(root, target, map, targetNode);    if(targetNode[0] == null) {        return 0;    }    return findMinTime(targetNode[0], map);}private static void fill(Node root, int target, Map<Node, Node> map, Node[] targetNode) {    if(root == null) {        return;    }    if(root.data == target) {        targetNode[0] = root;    }    if (root.left != null) {        map.put(root.left, root);        fill(root.left, target, map, targetNode);    }    if (root.right != null) {        map.put(root.right, root);        fill(root.right, target, map, targetNode);    }}private static int findMinTime(Node targetNode, Map<Node, Node> map) {    Map<Node, Boolean> visited = new HashMap<>();    Queue<Node> q = new LinkedList<>();    q.add(targetNode);    visited.put(targetNode, true);    int result = 0;    while(!q.isEmpty()) {        int size = q.size();        boolean anyBurnt = false;        for (int i = 0; i < size; i++) {            Node n = q.remove();            if(n.left != null && !visited.containsKey(n.left)) {                q.add(n.left);                visited.put(n.left, true);                anyBurnt = true;            }            if(n.right != null && !visited.containsKey(n.right)) {                q.add(n.right);                visited.put(n.right, true);                anyBurnt = true;            }            if(map.containsKey(n) && !visited.containsKey(map.get(n))) {                q.add(map.get(n));                visited.put(map.get(n), true);                anyBurnt = true;            }        }        if(anyBurnt) {            result++;        }    }    return result;} 
0
luffysama11 month ago
int burnTree(map<Node*,Node*>mp, Node* target){       map<Node* , int> vis;       queue<Node*> q;       q.push(target);       vis[target] = 1;       int maxi = 0;       while(!q.empty()){           int n = q.size();           bool f = 0;           while(n--){               Node* temp = q.front();               q.pop();               if(temp->left && !vis[temp->left]){                   f = 1;                   q.push(temp->left);                   vis[temp->left] = 1;               }               if(temp->right && !vis[temp->right]){                   f = 1;                   q.push(temp->right);                   vis[temp->right] = 1;               }               if(mp[temp] && !vis[mp[temp]]){                   f = 1;                   q.push(mp[temp]);                   vis[mp[temp]] = 1;               }           }           if(f) maxi++;       }       return maxi;   }    Node* getNodeAndMap(Node* root , int t , map<Node*,Node*>& mp){       queue<Node*>q;       q.push(root);       Node* ans;       while(!q.empty()){           int n = q.size();           while(n--){               Node* temp = q.front();               q.pop();               if(temp->data==t)                   ans = temp;               if(temp->left){                   mp[temp->left] = temp;                   q.push(temp->left);               }               if(temp->right){                   mp[temp->right] = temp;                   q.push(temp->right);               }           }       }              return ans;   }      int minTime(Node* root, int target)    {       // Your code goes here       map<Node*,Node*>mp;       Node* temp = getNodeAndMap(root,target,mp);       return burnTree(mp,temp);   }
0
aadityasharmax1 month ago
→ Using Print nodes k away from target problem logic.
class Solution {
  public:
    void burnTheTree(Node *root,int maxT,stack<Node *>&st,int &ans,Node* blocker){
        if(root==NULL || root==blocker) return;
        
        if(root->left!=NULL){
            burnTheTree(root->left,maxT+1,st,ans,blocker);
        }
        if(root->right!=NULL){
            burnTheTree(root->right,maxT+1,st,ans,blocker);
        }
        if(st.top() == root){
            st.pop();
            if(!st.empty()) burnTheTree(st.top(),maxT+1,st,ans,root);
        }
        ans = max(maxT,ans);
    }
    void rootToNodePath(Node *root,int target,vector<Node*> &v,stack<Node*>&s){
        if(root == NULL) return;
        v.push_back(root);
        if(root->data==target)
        {
            for(int i =0 ;i<v.size() ;i++) s.push(v[i]);
            return;
        }
        rootToNodePath(root->left,target,v,s);
        rootToNodePath(root->right,target,v,s);
        v.pop_back();
    }
    int minTime(Node* root, int target) 
    {
        // Your code goes here
        int ans = 0;
        stack<Node*> st;
        vector<Node*> v;
        rootToNodePath(root,target,v,st);
        Node* blocker = NULL;
        burnTheTree(st.top(),0,st,ans,blocker);
        return ans;
    }
};
+2
sahilarya20111 month ago
      public static Node createParentMapping(Node root, int target, HashMap<Node,Node>map){       Node res= null;       Queue<Node>q= new LinkedList<>();       q.add(root);       map.put(root,null);              while(!q.isEmpty()){           Node n= q.peek();           q.remove();                      if(n.data==target){               res=n;           }           if(n.left!=null){           map.put(n.left,n);           q.add(n.left);           }                      if(n.right!=null){               map.put(n.right,n);               q.add(n.right);           }       }       return res;   }         public static int burnTree(Node root, HashMap<Node,Node>map ) {       HashMap<Node,Boolean>visited= new HashMap<>();       Queue<Node>q= new LinkedList<>();       q.add(root);       visited.put(root,true);              int time=0;       while(!q.isEmpty()){           boolean flag= true;           int size= q.size();           for(int i=0; i<size; i++){               Node front= q.peek();               q.remove();                              if(front.left!=null && !visited.containsKey(front.left)){                   flag=true;                   q.add(front.left);                   visited.put(front.left,true);               }               if(front.right!=null && !visited.containsKey(front.right)){                   flag=true;                   q.add(front.right);                   visited.put(front.right,true);               }               if(map.get(front)!=null && !visited.containsKey(map.get(front))){                   flag=true;                                      q.add(map.get(front));                   visited.put(map.get(front),true);               }           }           if(flag==true)           time++;       }       return time-1;   }      public static int minTime(Node root, int target)    {       // Your code goes here              HashMap<Node,Node>map= new HashMap<>();       Node targetNode= createParentMapping(root,target,map);             int ans= burnTree(targetNode, map);       return ans;   }}
0
himanshu3198live1 month ago
 Node *source;
         unordered_map<Node*,Node*>getParent;
        
         void solve(Node *root,int target){
             
             if(!root) return;
             if(root->data==target) source=root;
             
             if(root->left) getParent[root->left]=root;
             if(root->right) getParent[root->right]=root;
             solve(root->left,target);
             solve(root->right,target);
         }
    int minTime(Node* root, int target) 
    {
        // Your code goes here
           getParent[root]==root;
           solve(root,target);
            
            if(root and !root->left and !root->right) return 0;
            
           queue<Node*>q;
           set<Node*>vis;
           q.push(source);
           int time=0;
           while(!q.empty()){
               
               int size=q.size();
               time++;
               while(size--){
                   
                   Node *curr=q.front();
                              q.pop();
                              
                    if(vis.count(curr)==1) break;  
                    vis.insert(curr);
                    
                    if(curr->left){
                       
                       if((curr->left->left or curr->left->right) and !vis.count(curr->left)){
                           
                           q.push(curr->left);
                       }
                   }
                   if(curr->right){
                        if((curr->right->left or curr->right->right) and !vis.count(curr->right)){
                           
                           q.push(curr->right);
                       }
                       
                   }
                   
                   if(getParent[curr]){
                       
                       if(vis.count(getParent[curr])==0){
                           q.push(getParent[curr]);
                       }
                   }
                   
               }
               
               
           }
         
           return time;
           
           
    }
+1
creator23031 month ago

class Solution {
  public:
  int ans=1;
  unordered_map<Node* ,  Node*> mp ;
 
 Node *T=NULL ;
 
 
 unordered_map<Node*, bool > visited ;
 
 void PreOrder(Node *root,int target)
 {
     if(!root)
        return ;
     
     if(root->data==target)
     T = root ;
     if(root->left)
     {
         mp[root->left] =root ;
     }
     if(root->right)
     {
         mp[root->right] = root ;
     }
     
     PreOrder(root->left,target) ;
     PreOrder(root->right,target) ;
 }
   
    
    
    
    

    int minTime(Node* root, int target) 
    {
        
        if(!root)
            return 0 ;
            
        mp[root] = NULL ;
        int t= 0;
        Node* r=root;
        
         PreOrder(root, target);
     
         
         queue<Node* > q ;
         q.push(T);
         
         while(!q.empty())
         {
             int sz=q.size(); 
             
             while(sz--)
             {
                 Node *temp = q.front() ;
                 q.pop();
                
                 
                
                  if(temp->left and !visited[temp->left])
                  {
                    q.push(temp->left) ;visited[temp->left] =1 ;
                      
                  }
                 
                 if(temp->right and !visited[temp->right])
                 {
                    q.push(temp->right)  ; visited[temp->right]=1 ;
                     
                 }
                    
                if(mp[temp]and !visited[mp[temp]])
                 {
                   
                    q.push(mp[temp]) ;visited[mp[temp]]=1;
                    
                 }
             }
           
             t++ ;
         }
        return t-1;
    }
        

};
 
+1
himanshu11042003singh1 month ago
class Solution { public: Node* createParentMapping(Node* root,int target,map<Node*,Node*>&nodeToParent){     Node* res= NULL;     queue<Node*>q;     q.push(root);     nodeToParent[root]=NULL;     while(!q.empty()){         Node* front= q.front();         q.pop();         if(front->data==target){             res= front;         }         if(front->left){             nodeToParent[front->left]=front;             q.push(front->left);                      }         if(front->right){             nodeToParent[front->right]=front;             q.push(front->right);         }              }     return res;      } int burnTree(Node* root,map<Node*,Node*>&nodeToParent){     map<Node*,bool>visited;     queue<Node*>q;     q.push(root);     visited[root]=true;     int ans=0;     while(!q.empty()){         bool flag=0;         int size=q.size();         for(int i=0;i<size;i++){             Node* front= q.front();             q.pop();             if(front->left&&!visited[front->left]){                 flag=1;                 q.push(front->left);                 visited[front->left]=1;             }             if(front->right&&!visited[front->right]){                 flag=1;                 q.push(front->right);                 visited[front->right]=1;             }             if(nodeToParent[front]&&!visited[nodeToParent[front]]){                 flag=1;                 q.push(nodeToParent[front]);                 visited[nodeToParent[front]]=1;             }                      }         if(flag==1){             ans++;         }     }     return ans; }   int minTime(Node* root, int target)    {       // Your code goes here       map<Node*,Node*>nodeToParent;       Node* targetNode= createParentMapping(root,target,nodeToParent);       int ans= burnTree(targetNode,nodeToParent);       return ans;          }};
We strongly recommend solving this problem on your own before viewing its editorial. Do you still
                    want to view the editorial?
 Login to access your submissions. 

Problem


Contest

Reset the IDE using the second button on the top right corner.
Avoid using static/global variables in your code as your code is tested against multiple test cases and these tend to retain their previous values.
Passing the Sample/Custom Test cases does not guarantee the correctness of code. On submission, your code is tested against multiple test cases consisting of all possible corner cases and stress constraints.
You can access the hints to get an idea about what is expected of you as well as the final solution code.
You can view the solutions submitted by other users from the submission tab.