Open In App

Simple Recursive solution to check whether BST contains dead end

Last Updated : 06 Jun, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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: root[] = [8, 5, 9, 2, 7, N, N, 1]
Output: true
Explanation: Node 1 is a Dead End in the given BST.

Input: root[] = [8, 7, 10, 2, N, 9, 13]
Output: true
Explanation: Node 9 is a Dead End in the given BST.

Observation:

A dead end in a Binary Search Tree (BST) refers to a leaf node where no further insertions can be made without violating the properties of the BST. Since BSTs typically contain only positive integers greater than 0, a node becomes a dead end when both of its adjacent values that is, (value - 1) and (value + 1) — are already present in the tree. In such cases, no new node can be inserted in that position while maintaining the BST's structural rules.

[Naive Approach] Using Recursion - O(n * h) time and O(h) space

The idea is iterate through each leaf node, and check whether values value - 1 and value + 1 exists in the tree. If these values exists, return true.

Note: For value 0, we return true as this value cannot be added to the tree.

C++
// C++ program to Check whether BST contains Dead End or not
#include <bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node *left, *right;

    Node(int val){
        data = val;
        left = nullptr;
        right = nullptr;
    }
};

bool findVal(Node* root, int val) {
    
    // For non-positive values, return true 
    // (as these values cannot be inserted)
    if (val <= 0) return true;
    
    if (root == nullptr) return false;
    
    if (root->data == val) return true;
    else if (root->data < val) return findVal(root->right, val);
    return findVal(root->left, val);
}

bool dfs(Node* curr, Node* root) {
    
    // Base Case 
    if (curr == nullptr) return false;
    
    // If value val - 1 and val + 1 already 
    // exists in the tree, and this node is 
    // a leaf node, return true.
    if (curr->left == nullptr && curr->right == nullptr) {
        int val = curr->data;
        
        return findVal(root, val-1) && findVal(root, val+1);
    }
    
    return dfs(curr->left, root) || dfs(curr->right, root);
}

bool isDeadEnd(Node *root) {
    
    return dfs(root, root);
}

int main() {
    
    Node* root = new Node(8);
    root->left = new Node(5);
    root->right = new Node(9);
    root->left->left = new Node(2);
    root->left->right = new Node(7);
    root->left->left->left = new Node(1);

    if (isDeadEnd(root)) {
        cout << "true" << endl;
    } else {
        cout << "false" << endl;
    }

    return 0;
}
Java
// Java program to Check whether BST contains Dead End or not

class Node {
    int data;
    Node left, right;

    Node(int val) {
        data = val;
        left = null;
        right = null;
    }
}

class GfG {
    static boolean findVal(Node root, int val) {
        
        // For non-positive values, return true 
        // (as these values cannot be inserted)
        if (val <= 0) return true;
        
        if (root == null) return false;
        
        if (root.data == val) return true;
        else if (root.data < val) return findVal(root.right, val);
        return findVal(root.left, val);
    }

    static boolean dfs(Node curr, Node root) {
        
        // Base Case 
        if (curr == null) return false;
        
        // If value val - 1 and val + 1 already 
        // exists in the tree, and this node is 
        // a leaf node, return true.
        if (curr.left == null && curr.right == null) {
            int val = curr.data;
            
            return findVal(root, val-1) && findVal(root, val+1);
        }
        
        return dfs(curr.left, root) || dfs(curr.right, root);
    }

    static boolean isDeadEnd(Node root) {
        
        return dfs(root, root);
    }

    public static void main(String[] args) {
        
        Node root = new Node(8);
        root.left = new Node(5);
        root.right = new Node(9);
        root.left.left = new Node(2);
        root.left.right = new Node(7);
        root.left.left.left = new Node(1);

        System.out.println(isDeadEnd(root));
    }
}
Python
# Python program to Check whether BST contains Dead End or not

class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

def findVal(root, val):
    
    # For non-positive values, return true 
    # (as these values cannot be inserted)
    if val <= 0:
        return True
    
    if root is None:
        return False
    
    if root.data == val:
        return True
    elif root.data < val:
        return findVal(root.right, val)
    return findVal(root.left, val)

def dfs(curr, root):
    
    # Base Case 
    if curr is None:
        return False
    
    # If value val - 1 and val + 1 already 
    # exists in the tree, and this node is 
    # a leaf node, return true.
    if curr.left is None and curr.right is None:
        val = curr.data
        
        return findVal(root, val-1) and findVal(root, val+1)
    
    return dfs(curr.left, root) or dfs(curr.right, root)

def isDeadEnd(root):
    
    return dfs(root, root)

if __name__ == "__main__":
    
    root = Node(8)
    root.left = Node(5)
    root.right = Node(9)
    root.left.left = Node(2)
    root.left.right = Node(7)
    root.left.left.left = Node(1)

    if isDeadEnd(root):
        print("true")
    else:
        print("false")
C#
// C# program to Check whether BST contains Dead End or not

using System;

class Node {
    public int data;
    public Node left, right;

    public Node(int val) {
        data = val;
        left = null;
        right = null;
    }
}

class GfG {
    static bool FindVal(Node root, int val) {
        
        // For non-positive values, return true 
        // (as these values cannot be inserted)
        if (val <= 0) return true;
        
        if (root == null) return false;
        
        if (root.data == val) return true;
        else if (root.data < val) return FindVal(root.right, val);
        return FindVal(root.left, val);
    }

    static bool Dfs(Node curr, Node root) {
        
        // Base Case 
        if (curr == null) return false;
        
        // If value val - 1 and val + 1 already 
        // exists in the tree, and this node is 
        // a leaf node, return true.
        if (curr.left == null && curr.right == null) {
            int val = curr.data;
            
            return FindVal(root, val-1) && FindVal(root, val+1);
        }
        
        return Dfs(curr.left, root) || Dfs(curr.right, root);
    }

    static bool IsDeadEnd(Node root) {
        
        return Dfs(root, root);
    }

    static void Main() {
       
        Node root = new Node(8);
        root.left = new Node(5);
        root.right = new Node(9);
        root.left.left = new Node(2);
        root.left.right = new Node(7);
        root.left.left.left = new Node(1);

        if (IsDeadEnd(root)) {
            Console.WriteLine("true");
        } else {
            Console.WriteLine("false");
        }
    }
}
JavaScript
// JavaScript program to Check whether BST contains Dead End or not

class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

function findVal(root, val) {
    
    // For non-positive values, return true 
    // (as these values cannot be inserted)
    if (val <= 0) return true;
    
    if (root === null) return false;
    
    if (root.data === val) return true;
    else if (root.data < val) return findVal(root.right, val);
    return findVal(root.left, val);
}

function dfs(curr, root) {
    
    // Base Case 
    if (curr === null) return false;
    
    // If value val - 1 and val + 1 already 
    // exists in the tree, and this node is 
    // a leaf node, return true.
    if (curr.left === null && curr.right === null) {
        let val = curr.data;
        
        return findVal(root, val-1) && findVal(root, val+1);
    }
    
    return dfs(curr.left, root) || dfs(curr.right, root);
}

function isDeadEnd(root) {
    
    return dfs(root, root);
}

// Driver Code  
let root = new Node(8);
root.left = new Node(5);
root.right = new Node(9);
root.left.left = new Node(2);
root.left.right = new Node(7);
root.left.left.left = new Node(1);

if (isDeadEnd(root)) {
    console.log("true");
} else {
    console.log("false");
}

Output
true

[Expected Approach] Using Recursion and Range Values - O(n) time and O(h) space

The idea is to perform depth first search traversal on the tree, while maintaining the range of each subtree root. If for any leaf node, the size of range becomes 1 (this value is taken by leaf node already), it means no node can be inserted to this leaf node, and hence it is a dead end.

Step by step approach:

  1. Perform Depth first search on the root node and initialize the range as [1, Integer Maximum].
  2. For each node:
    • If node is null, return false.
    • If node is leaf node and the range of node is 1, return true as no other node can be inserted.
    • Recur for left and right subtree.

Illustration:

C++
// C++ program to Check whether BST contains Dead End or not
#include <bits/stdc++.h>
using namespace std;

class Node {
public:
    int data;
    Node *left, *right;

    Node(int val){
        data = val;
        left = nullptr;
        right = nullptr;
    }
};

// Here mini and maxi defines the range of 
// the subtree root. If the range consists 
// only of 1 value (root value), it means 
// no other value cannot be added to this.
bool dfs(Node* root, int mini, int maxi) {
    
    // Base Case 
    if (root == nullptr) return false;
    
    // If leaf node and no range left 
    if (root->left == nullptr && root->right == nullptr &&
    mini == maxi) {
        return true;
    }
    
    return dfs(root->left, mini, root->data-1) || 
    dfs(root->right, root->data+1, maxi);
}

bool isDeadEnd(Node *root) {
    
    return dfs(root, 1, INT_MAX);
}

int main() {
    
    Node* root = new Node(8);
    root->left = new Node(5);
    root->right = new Node(9);
    root->left->left = new Node(2);
    root->left->right = new Node(7);
    root->left->left->left = new Node(1);

    if (isDeadEnd(root)) {
        cout << "true" << endl;
    } else {
        cout << "false" << endl;
    }

    return 0;
}
Java
// Java program to Check whether BST contains Dead End or not

class Node {
    int data;
    Node left, right;

    Node(int val) {
        data = val;
        left = null;
        right = null;
    }
}

class GfG {
    
    // Here mini and maxi defines the range of 
    // the subtree root. If the range consists 
    // only of 1 value (root value), it means 
    // no other value cannot be added to this.
    static boolean dfs(Node root, int mini, int maxi) {
        
        // Base Case 
        if (root == null) return false;
        
        // If leaf node and no range left 
        if (root.left == null && root.right == null &&
        mini == maxi) {
            return true;
        }
        
        return dfs(root.left, mini, root.data-1) || 
        dfs(root.right, root.data+1, maxi);
    }

    static boolean isDeadEnd(Node root) {
        
        return dfs(root, 1, Integer.MAX_VALUE);
    }

    public static void main(String[] args) {
        
        Node root = new Node(8);
        root.left = new Node(5);
        root.right = new Node(9);
        root.left.left = new Node(2);
        root.left.right = new Node(7);
        root.left.left.left = new Node(1);

        System.out.println(isDeadEnd(root));
        
    }
}
Python
# Python program to Check whether BST contains Dead End or not

class Node:
    def __init__(self, val):
        self.data = val
        self.left = None
        self.right = None

# Here mini and maxi defines the range of 
# the subtree root. If the range consists 
# only of 1 value (root value), it means 
# no other value cannot be added to this.
def dfs(root, mini, maxi):
    
    # Base Case 
    if root is None:
        return False
    
    # If leaf node and no range left 
    if root.left is None and root.right is None and mini == maxi:
        return True
    
    return dfs(root.left, mini, root.data-1) or dfs(root.right, root.data+1, maxi)

def isDeadEnd(root):
    
    return dfs(root, 1, float('inf'))

if __name__ == "__main__":
    
    root = Node(8)
    root.left = Node(5)
    root.right = Node(9)
    root.left.left = Node(2)
    root.left.right = Node(7)
    root.left.left.left = Node(1)

    if isDeadEnd(root):
        print("true")
    else:
        print("false")
C#
// C# program to Check whether BST contains Dead End or not

using System;

class Node {
    public int data;
    public Node left, right;

    public Node(int val) {
        data = val;
        left = null;
        right = null;
    }
}

class GfG {
    
    // Here mini and maxi defines the range of 
    // the subtree root. If the range consists 
    // only of 1 value (root value), it means 
    // no other value cannot be added to this.
    static bool Dfs(Node root, int mini, int maxi) {
        
        // Base Case 
        if (root == null) return false;
        
        // If leaf node and no range left 
        if (root.left == null && root.right == null &&
        mini == maxi) {
            return true;
        }
        
        return Dfs(root.left, mini, root.data-1) || 
        Dfs(root.right, root.data+1, maxi);
    }

    static bool IsDeadEnd(Node root) {
        
        return Dfs(root, 1, int.MaxValue);
    }

    static void Main() {
        
        Node root = new Node(8);
        root.left = new Node(5);
        root.right = new Node(9);
        root.left.left = new Node(2);
        root.left.right = new Node(7);
        root.left.left.left = new Node(1);

        if (IsDeadEnd(root)) {
            Console.WriteLine("true");
        } else {
            Console.WriteLine("false");
        }
    }
}
JavaScript
// JavaScript program to Check whether BST contains Dead End or not

class Node {
    constructor(val) {
        this.data = val;
        this.left = null;
        this.right = null;
    }
}

// Here mini and maxi defines the range of 
// the subtree root. If the range consists 
// only of 1 value (root value), it means 
// no other value cannot be added to this.
function dfs(root, mini, maxi) {
    
    // Base Case 
    if (root === null) return false;
    
    // If leaf node and no range left 
    if (root.left === null && root.right === null &&
    mini === maxi) {
        return true;
    }
    
    return dfs(root.left, mini, root.data-1) || 
    dfs(root.right, root.data+1, maxi);
}

function isDeadEnd(root) {
    
    return dfs(root, 1, Number.MAX_SAFE_INTEGER);
}

// Driver Code
let root = new Node(8);
root.left = new Node(5);
root.right = new Node(9);
root.left.left = new Node(2);
root.left.right = new Node(7);
root.left.left.left = new Node(1);

console.log(isDeadEnd(root));

Output
true

Related Article:


Article Tags :
Practice Tags :

Similar Reads