# Check whether BST contains Dead End or not

Last Updated : 12 Apr, 2024

Given a Binary search Tree that contains positive integer values greater than 0. The task is to check whether the BST contains a dead end or not. Here Dead End means, we are not able to insert any element after that node.

Examples:

`Input :        8             /   \            5      9         /   \        2     7       /      1               Output : YesExplanation : Node "1" is the dead End because         after that we cant insert any element.       Input :       8            /   \            7     10         /      /   \        2      9     13Output : YesExplanation : We can't insert any element at               node 9.  `

If we take a closer look at the problem, we can notice that we basically need to check if there is a leaf node with value x such that x+1 and x-1 exist in BST with the exception of x = 1. For x = 1, we can’t insert 0 as the problem statement says BST contains positive integers only.

To implement the above idea we first traverse the whole BST and store all nodes in a set. We also store all leaves in a separate hash to avoid re-traversal of BST. Finally, we check for every leaf node x, if x-1 and x+1 are present in set or not.

Below is a C++ implementation of the above idea.

C++ ```#include<bits/stdc++.h> using namespace std; // A BST node struct Node { int data; struct Node *left, *right; }; // A utility function to create a new node Node *newNode(int data) { Node *temp = new Node; temp->data = data; temp->left = temp->right = NULL; return temp; } /* A utility function to insert a new Node with given key in BST */ struct Node* insert(struct Node* node, int key) { /* If the tree is empty, return a new Node */ if (node == NULL) return newNode(key); /* Otherwise, recur down the tree */ if (key < node->data) node->left = insert(node->left, key); else if (key > node->data) node->right = insert(node->right, key); /* return the (unchanged) Node pointer */ return node; } // Returns true if there is a dead end in tree, // else false. bool isDeadEndUtil(Node *root, int low, int high) { // Base case if (root == NULL) return false; // Check if current node falls within the range if (root->data >= low && root->data <= high) return true; // Recur for left and right subtrees return isDeadEndUtil(root->left, low, root->data - 1) || isDeadEndUtil(root->right, root->data + 1, high); } bool isDeadEnd(Node *root) { return isDeadEndUtil(root, 1, INT_MAX); } // Driver program int main() { Node *root = NULL; root = insert(root, 8); root = insert(root, 5); root = insert(root, 2); root = insert(root, 3); root = insert(root, 7); root = insert(root, 11); root = insert(root, 4); if (isDeadEnd(root) == true) cout << "Yes " << endl; else cout << "No " << endl; return 0; } ``` Java ```// Java program check whether BST contains // dead end or not import java.util.*; class Main { // create two empty hash sets that store all // BST elements and leaf nodes respectively. static HashSet<Integer> all_nodes = new HashSet<Integer>(); static HashSet<Integer> leaf_nodes = new HashSet<Integer>(); /* A utility function to insert a new Node with given key in BST */ public static Node insert(Node node, int key) { /* If the tree is empty, return a new Node */ if (node == null) return new Node(key); /* Otherwise, recur down the tree */ if (key < node.data) node.left = insert(node.left, key); else if (key > node.data) node.right = insert(node.right, key); /* return the Node */ return node; } // Function to store all node of given binary search // tree public static void storeNodes(Node root) { if (root == null) return; // store all node of binary search tree all_nodes.add(root.data); // store leaf node in leaf_hash if (root.left == null && root.right == null) { leaf_nodes.add(root.data); return; } // recur call rest tree storeNodes(root.left); storeNodes(root.right); } // Returns true if there is a dead end in tree, // else false. public static boolean isDeadEnd(Node root) { // Base case if (root == null) return false; // insert 0 in 'all_nodes' for handle case // if bst contain value 1 all_nodes.add(0); // Call storeNodes function to store all BST Node storeNodes(root); // Traversal leaf node and check Tree contain // continuous sequence of // size tree or Not for (int i : leaf_nodes) { int x = i; // Here we check first and last element of // continuous sequence that are x-1 & x+1 if (all_nodes.contains(x + 1) && all_nodes.contains(x - 1)) { return true; } } return false; } // Driver program public static void main(String[] args) { /* 8 / \ 5 11 / \ 2 7 \ 3 \ 4 */ Node root = null; root = insert(root, 8); root = insert(root, 5); root = insert(root, 2); root = insert(root, 3); root = insert(root, 7); root = insert(root, 11); root = insert(root, 4); if (isDeadEnd(root) == true) System.out.println("Yes"); else System.out.println("No"); } } // A BST node class Node { int data; Node left, right; Node(int data) { this.data = data; left = null; right = null; } } // This code is contributed by Tapesh(tapeshdua420) ``` Python3 ```# Python 3 program check # whether BST contains # dead end or not all_nodes = set() leaf_nodes = set() # A BST node class newNode: def __init__(self, data): self.data = data self.left = None self.right = None ''' A utility function to insert a new Node with given key in BST ''' def insert(node, key): '''/* If the tree is empty, return a new Node */ ''' if (node == None): return newNode(key) # Otherwise, recur down # the tree if (key < node.data): node.left = insert(node.left, key) elif (key > node.data): node.right = insert(node.right, key) # return the (unchanged) # Node pointer return node # Function to store all node # of given binary search tree def storeNodes(root): global all_nodes global leaf_nodes if (root == None): return # store all node of binary # search tree all_nodes.add(root.data) # store leaf node in leaf_hash if (root.left == None and root.right == None): leaf_nodes.add(root.data) return # recur call rest tree storeNodes(root. left) storeNodes(root.right) # Returns true if there is # a dead end in tree, # else false. def isDeadEnd(root): global all_nodes global leaf_nodes # Base case if (root == None): return False # create two empty hash # sets that store all BST # elements and leaf nodes # respectively. # insert 0 in 'all_nodes' # for handle case if bst # contain value 1 all_nodes.add(0) # Call storeNodes function # to store all BST Node storeNodes(root) # Traversal leaf node and # check Tree contain # continuous sequence of # size tree or Not for x in leaf_nodes: # Here we check first and # last element of continuous # sequence that are x-1 & x+1 if ((x + 1) in all_nodes and (x - 1) in all_nodes): return True return False # Driver code if __name__ == '__main__': '''/* 8 / \ 5 11 / \ 2 7 \ 3 \ 4 */ ''' root = None root = insert(root, 8) root = insert(root, 5) root = insert(root, 2) root = insert(root, 3) root = insert(root, 7) root = insert(root, 11) root = insert(root, 4) if(isDeadEnd(root) == True): print("Yes") else: print("No") # This code is contributed by bgangwar59 ``` C# ```// C# code for the above approach using System; using System.Collections.Generic; // A BST node public class Node { public int data; public Node left, right; public Node(int data) { this.data = data; left = null; right = null; } } public class GFG { // create two empty hash sets that store all // BST elements and leaf nodes respectively. static HashSet<int> all_nodes = new HashSet<int>(); static HashSet<int> leaf_nodes = new HashSet<int>(); /* A utility function to insert a new Node with given key in BST */ public static Node insert(Node node, int key) { /* If the tree is empty, return a new Node */ if (node == null) return new Node(key); /* Otherwise, recur down the tree */ if (key < node.data) node.left = insert(node.left, key); else if (key > node.data) node.right = insert(node.right, key); /* return the Node */ return node; } // Function to store all node of given binary search // tree public static void storeNodes(Node root) { if (root == null) return; // store all node of binary search tree all_nodes.Add(root.data); // store leaf node in leaf_hash if (root.left == null && root.right == null) { leaf_nodes.Add(root.data); return; } // recur call rest tree storeNodes(root.left); storeNodes(root.right); } // Returns true if there is a dead end in tree, // else false. public static bool isDeadEnd(Node root) { // Base case if (root == null) return false; // insert 0 in 'all_nodes' for handle case // if bst contain value 1 all_nodes.Add(0); // Call storeNodes function to store all BST Node storeNodes(root); // Traversal leaf node and check Tree contain // continuous sequence of // size tree or Not foreach(int i in leaf_nodes) { int x = i; // Here we check first and last element of // continuous sequence that are x-1 & x+1 if (all_nodes.Contains(x + 1) && all_nodes.Contains(x - 1)) { return true; } } return false; } static public void Main() { // Code /* 8 / \ 5 11 / \ 2 7 \ 3 \ 4 */ Node root = null; root = insert(root, 8); root = insert(root, 5); root = insert(root, 2); root = insert(root, 3); root = insert(root, 7); root = insert(root, 11); root = insert(root, 4); if (isDeadEnd(root) == true) Console.WriteLine("Yes"); else Console.WriteLine("No"); } } // This code is contributed by lokesh. ``` Javascript ```class Node { constructor(data) { this.data = data; this.left = null; this.right = null; } } // A utility function to create a new node function newNode(data) { let temp = new Node(data); return temp; } /* A utility function to insert a new Node with given key in BST */ function insert(node, key) { /* If the tree is empty, return a new Node */ if (node == null) return newNode(key); /* Otherwise, recur down the tree */ if (key < node.data) { node.left = insert(node.left, key); } else if (key > node.data) { node.right = insert(node.right, key); } /* return the (unchanged) Node pointer */ return node; } // Function to store all node of given binary search tree function storeNodes(root, all_nodes, leaf_nodes) { if (root == null) return; // store all node of binary search tree all_nodes.add(root.data); // store leaf node in leaf_nodes if (root.left == null && root.right == null) { leaf_nodes.add(root.data); return; } // recur call rest tree storeNodes(root.left, all_nodes, leaf_nodes); storeNodes(root.right, all_nodes, leaf_nodes); } // Returns true if there is a dead end in tree, // else false. function isDeadEnd(root) { // Base case if (root == null) return false; // create two empty sets that store all // BST elements and leaf nodes respectively. let all_nodes = new Set(); let leaf_nodes = new Set(); // insert 0 in 'all_nodes' for handle case // if bst contain value 1 all_nodes.add(0); // Call storeNodes function to store all BST Node storeNodes(root, all_nodes, leaf_nodes); // Traversal leaf node and check Tree contain // continuous sequence of // size tree or Not for (let i of leaf_nodes) { let x = i; // Here we check first and last element of // continuous sequence that are x-1 & x+1 if (all_nodes.has(x + 1) && all_nodes.has(x - 1)) return true; } return false; } // Driver program /* 8 / \ 5 11 / \ 2 7 \ 3 \ 4 */ let root = null; root = insert(root, 8); root = insert(root, 5); root = insert(root, 2); root = insert(root, 3); root = insert(root, 7); root = insert(root, 11); root = insert(root, 4); if (isDeadEnd(root) == true) { console.log("Yes"); } else { console.log("No"); } // This code is contributed by lokeshpotta20. ```

Output
`Yes `

Time Complexity : O(n)

The time complexity of the above algorithm is O(n) as we are traversing the entire tree to check for the dead end.

Space complexity: O(n)

The space complexity of the above algorithm is O(n) as we need to store all the elements in the unordered_set which is of size n.

Improved Approach

In the above approach we are using 2 hashmaps , one for storing all nodes and one for storing leaf nodes , instead of using 2 maps we can do this problem with 1 hashmap also .

We can pass the hashmap of all nodes and check if for node x there exists a x-1 and x+1 or not. If we got a node for which x+1 and x-1 both are present we will return true otherwise we will return false

Implementation:

C++ ```// C++ program check whether BST contains // dead end or not #include<bits/stdc++.h> using namespace std; // A BST node struct Node { int data; struct Node *left, *right; }; // A utility function to create a new node Node *newNode(int data) { Node *temp = new Node; temp->data = data; temp->left = temp->right = NULL; return temp; } /* A utility function to insert a new Node with given key in BST */ struct Node* insert(struct Node* node, int key) { /* If the tree is empty, return a new Node */ if (node == NULL) return newNode(key); /* Otherwise, recur down the tree */ if (key < node->data) node->left = insert(node->left, key); else if (key > node->data) node->right = insert(node->right, key); /* return the (unchanged) Node pointer */ return node; } void findallNodes(Node* root,map<int,int> &allnodes) { if(root == NULL) return ; allnodes[root->data] = 1; findallNodes(root->left,allnodes); findallNodes(root->right,allnodes); } bool check(Node* root,map<int,int> &allnodes) { if(root == NULL) return false; if(root->left == NULL and root->right == NULL) { int pre = root->data - 1; int next = root->data + 1; if(allnodes.find(pre) != allnodes.end() and allnodes.find(next) != allnodes.end()) return true; } return check(root->left,allnodes) or check(root->right,allnodes); } bool isDeadEnd(Node *root) { // Base case if (root == NULL) return false ; map<int,int> allnodes; // adding 0 for handling the exception of node having data = 1 allnodes[0] = 1; findallNodes(root,allnodes); return check(root,allnodes); } // Driver program int main() { /* 8 / \ 5 11 / \ 2 7 \ 3 \ 4 */ Node *root = NULL; root = insert(root, 8); root = insert(root, 5); root = insert(root, 2); root = insert(root, 3); root = insert(root, 7); root = insert(root, 11); root = insert(root, 4); if (isDeadEnd(root) == true) cout << "Yes " << endl; else cout << "No " << endl; return 0; } ``` Java ```// Java program check whether BST contains dead end or not import java.io.*; import java.util.*; // A BST node class Node { int data; Node left, right; Node(int data) { this.data = data; left = right = null; } } class GFG { Node root; void BST() { root = null; } // A utility function to insert a new Node with given // key in BST Node insert(Node node, int key) { // If the tree is empty, return a new node if (node == null) { return new Node(key); } // Otherwise, recur down the tree if (key < node.data) { node.left = insert(node.left, key); } else if (key > node.data) { node.right = insert(node.right, key); } // return the (unchanged) Node pointer return node; } void findAllNodes(Node root, Map<Integer, Integer> allNodes) { if (root == null) { return; } allNodes.put(root.data, 1); findAllNodes(root.left, allNodes); findAllNodes(root.right, allNodes); } boolean check(Node root, Map<Integer, Integer> allNodes) { if (root == null) { return false; } if (root.left == null && root.right == null) { int pre = root.data - 1; int next = root.data + 1; if (allNodes.containsKey(pre) && allNodes.containsKey(next)) { return true; } } return check(root.left, allNodes) || check(root.right, allNodes); } boolean isDeadEnd(Node root) { // Base case if (root == null) { return false; } Map<Integer, Integer> allNodes = new HashMap<Integer, Integer>(); // adding 0 for handling the exception of node // having date = 1 allNodes.put(0, 1); findAllNodes(root, allNodes); return check(root, allNodes); } public static void main(String[] args) { /* 8 / \ 5 11 / \ 2 7 \ 3 \ 4 */ GFG tree = new GFG(); Node root = null; root = tree.insert(root, 8); root = tree.insert(root, 5); root = tree.insert(root, 2); root = tree.insert(root, 3); root = tree.insert(root, 7); root = tree.insert(root, 11); root = tree.insert(root, 4); if (tree.isDeadEnd(root) == true) { System.out.println("Yes"); } else { System.out.println("No"); } } } // This code is contributed by lokeshmvs21. ``` Python ```# Python program check whether BST contains # dead end or not # A BST node class Node: def __init__(self, data): self.data = data self.left = None self.right = None # a utility function to create a new node def newNode(data): return Node(data) # a utility function to insert a new node # with given key in BST def insert(node, key): # if the tree is empty, return a new node if(node is None): return newNode(key) # otherwise , recur down the tree if(key < node.data): node.left = insert(node.left, key) elif(key > node.data): node.right = insert(node.right, key) # return the (unchanged) Node pointer return node allnodes = {} def findallNodes(root): if(root is None): return allnodes[root.data] = 1 findallNodes(root.left) findallNodes(root.right) def check(root): if(root is None): return False if(root.left is None and root.right is None): pre = root.data - 1 next = root.data + 1 if(allnodes.get(pre) is not None and allnodes.get(next) is not None): return True return check(root.left) or check(root.right) def isDeadEnd(root): if(root is None): return False allnodes[0] = 1 findallNodes(root) return check(root) # driver program root = None root = insert(root, 8) root = insert(root, 5) root = insert(root, 2) root = insert(root, 3) root = insert(root, 7) root = insert(root, 11) root = insert(root, 4) if(isDeadEnd(root) is True): print("Yes") else: print("No") # THIS CODE IS CONTRIBUTED BY KIRTI AGARWAL(KIRTIAGARWAL23121999) ``` C# ```// C# program check whether BST contains // dead end or not using System; using System.Linq; using System.Collections.Generic; class GFG { // Structure of a Query class Node { public int data; public Node left, right; public Node(int data) { this.data=data; this.left=left; this.right=right; } } /* A utility function to insert a new Node with given key in BST */ static Node insert(Node node, int key) { /* If the tree is empty, return a new Node */ if (node == null) return new Node(key); /* Otherwise, recur down the tree */ if (key < node.data) node.left = insert(node.left, key); else if (key > node.data) node.right = insert(node.right, key); /* return the (unchanged) Node pointer */ return node; } static void findallNodes(Node root,Dictionary<int,int> allnodes) { if(root == null) return ; allnodes.Add(root.data, 1); findallNodes(root.left,allnodes); findallNodes(root.right,allnodes); } static bool check(Node root,Dictionary<int,int> allnodes) { if(root == null) return false; if(root.left == null && root.right == null) { int pre = root.data - 1; int next = root.data + 1; if(allnodes.ContainsKey(pre) ==true && allnodes.ContainsKey(next) ==true) return true; } return check(root.left,allnodes) || check(root.right,allnodes); } static bool isDeadEnd(Node root) { // Base case if (root == null) return false ; Dictionary<int,int> allnodes=new Dictionary<int, int>(); // adding 0 for handling the exception of node having data = 1 allnodes.Add(0,1); findallNodes(root,allnodes); return check(root,allnodes); } // Driver program static public void Main() { /* 8 / \ 5 11 / \ 2 7 \ 3 \ 4 */ Node root = null; root = insert(root, 8); root = insert(root, 5); root = insert(root, 2); root = insert(root, 3); root = insert(root, 7); root = insert(root, 11); root = insert(root, 4); if (isDeadEnd(root) == true) Console.Write("Yes "); else Console.Write("No "); } } ``` Javascript ```// JavaScript program to check whether BST contains // dead end or not class Node{ constructor(data){ this.data = data; this.left = null; this.right = null; } } // A utility function to create a new node function newNode(data){ let temp = new Node(data); return temp; } // A utility functiion to insert a new node // with given key in BST function insert(node, key){ // If the tree is empty, return a new node if(node == null) return newNode(key); // Otherwise, recur down the tree if(key < node.data) node.left = insert(node.left, key); else if(key > node.data) node.right = insert(node.right, key); // return the (unchanged) Node pointer return node; } let allnodes = new Map(); function findallNodes(root){ if(root == null) return; allnodes.set(root.data, 1); findallNodes(root.left); findallNodes(root.right); } function check(root){ if(root == null) return false; if(root.left == null && root.right == null){ let pre = root.data - 1; let next = root.data + 1; if(allnodes.has(pre) != false && allnodes.has(next) != false){ return true; } } return check(root.left) || check(root.right); } function isDeadEnd(root){ // Base Case if(root == null) return false; allnodes.set(0,1); findallNodes(root); return check(root); } // Driver Program /* 8 / \ 5 11 / \ 2 7 \ 3 \ 4 */ let root = null; root = insert(root, 8); root = insert(root, 5); root = insert(root, 2); root = insert(root, 3); root = insert(root, 7); root = insert(root, 11); root = insert(root, 4); if(isDeadEnd(root) == true){ console.log("Yes"); }else{ console.log("No"); } // This code is contributed by Yash Agarwal(yashagarwal2852002) ```

Output
`Yes `

Time Complexity: O(N) where N is the Number of nodes in a given binary tree.
Auxiliary Space: O(N)

Previous
Next