 Open in App
Not now

# Find the largest Perfect Subtree in a given Binary Tree

• Difficulty Level : Medium
• Last Updated : 31 Jan, 2023

Given a Binary Tree, the task is to find the size of largest Perfect sub-tree in the given Binary Tree.

Perfect Binary Tree – A Binary tree is Perfect Binary Tree in which all internal nodes have two children and all leaves are at the same level.

Examples:

```Input:
1
/   \
2     3
/  \   /
4    5 6
Output:
Size : 3
Inorder Traversal : 4 2 5
The following sub-tree is the maximum size Perfect sub-tree
2
/  \
4    5

Input:
50
/      \
30         60
/   \      /    \
5    20   45      70
/  \     /  \
10   85  65  80
Output:
Size : 7
Inorder Traversal : 10 45 85 60 65 70 80```

Approach: Simply traverse the tree in bottom up manner. Then on coming up in recursion from child to parent, we can pass information about sub-trees to the parent. The passed information can be used by the parent to do the Perfect Tree test (for parent node) only in constant time. A left sub-tree need to tell the parent whether it is a Perfect Binary Tree or not and also need to pass max height of the Perfect Binary Tree coming from left child. Similarly, the right sub-tree also needs to pass max height of Perfect Binary Tree coming from right child.

The sub-trees need to pass the following information up the tree for finding the largest Perfect sub-tree so that we can compare the maximum height with the parent’s data to check the Perfect Binary Tree property.

1. There is a bool variable to check whether the left child or the right child sub-tree is Perfect or not.
2. From left and right child calls in recursion we find out if parent sub-tree if Perfect or not by following 2 cases:
• If both left child and right child are perfect binary tree and have same heights then parent is also a Perfect Binary Tree with height plus one of its child.
• If the above case is not true then parent cannot be perfect binary tree and simply returns max size Perfect Binary Tree coming from left or right sub-tree by comparing their heights.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach``#include ``using` `namespace` `std;` `// Node structure of the tree``struct` `node {``    ``int` `data;``    ``struct` `node* left;``    ``struct` `node* right;``};` `// To create a new node``struct` `node* newNode(``int` `data)``{``    ``struct` `node* node = (``struct` `node*)``malloc``(``sizeof``(``struct` `node));``    ``node->data = data;``    ``node->left = NULL;``    ``node->right = NULL;``    ``return` `node;``};` `// Structure for return type of``// function findPerfectBinaryTree``struct` `returnType {` `    ``// To store if sub-tree is perfect or not``    ``bool` `isPerfect;` `    ``// Height of the tree``    ``int` `height;` `    ``// Root of biggest perfect sub-tree``    ``node* rootTree;``};` `// Function to return the biggest``// perfect binary sub-tree``returnType findPerfectBinaryTree(``struct` `node* root)``{` `    ``// Declaring returnType that``    ``// needs to be returned``    ``returnType rt;` `    ``// If root is NULL then it is considered as``    ``// perfect binary tree of height 0``    ``if` `(root == NULL) {``        ``rt.isPerfect = ``true``;``        ``rt.height = 0;``        ``rt.rootTree = NULL;``        ``return` `rt;``    ``}` `    ``// Recursive call for left and right child``    ``returnType lv = findPerfectBinaryTree(root->left);``    ``returnType rv = findPerfectBinaryTree(root->right);` `    ``// If both left and right sub-trees are perfect and``    ``// there height is also same then sub-tree root``    ``// is also perfect binary subtree with height``    ``// plus one of its child sub-trees``    ``if` `(lv.isPerfect && rv.isPerfect && lv.height == rv.height) {``        ``rt.height = lv.height + 1;``        ``rt.isPerfect = ``true``;``        ``rt.rootTree = root;``        ``return` `rt;``    ``}` `    ``// Else this sub-tree cannot be a perfect binary tree``    ``// and simply return the biggest sized perfect sub-tree``    ``// found till now in the left or right sub-trees``    ``rt.isPerfect = ``false``;``    ``rt.height = max(lv.height, rv.height);``    ``rt.rootTree = (lv.height > rv.height ? lv.rootTree : rv.rootTree);``    ``return` `rt;``}` `// Function to print the inorder traversal of the tree``void` `inorderPrint(node* root)``{``    ``if` `(root != NULL) {``        ``inorderPrint(root->left);``        ``cout << root->data << ``" "``;``        ``inorderPrint(root->right);``    ``}``}` `// Driver code``int` `main()``{``    ``// Create tree``    ``struct` `node* root = newNode(1);``    ``root->left = newNode(2);``    ``root->right = newNode(3);``    ``root->left->left = newNode(4);``    ``root->left->right = newNode(5);``    ``root->right->left = newNode(6);` `    ``// Get the biggest sizes perfect binary sub-tree``    ``struct` `returnType ans = findPerfectBinaryTree(root);` `    ``// Height of the found sub-tree``    ``int` `h = ans.height;` `    ``cout << ``"Size : "` `<< ``pow``(2, h) - 1 << endl;` `    ``// Print the inorder traversal of the found sub-tree``    ``cout << ``"Inorder Traversal : "``;``    ``inorderPrint(ans.rootTree);` `    ``return` `0;``}`

## Java

 `// Java implementation of the approach``import` `java.util.*;` `class` `GFG``{``    ` `// Node structure of the tree``static` `class` `node``{``    ``int` `data;``    ``node left;``    ``node right;``};` `// To create a new node``static` `node newNode(``int` `data)``{``    ``node node = ``new` `node();``    ``node.data = data;``    ``node.left = ``null``;``    ``node.right = ``null``;``    ``return` `node;``};` `// Structure for return type of``// function findPerfectBinaryTree``static` `class` `returnType``{` `    ``// To store if sub-tree is perfect or not``    ``boolean` `isPerfect;` `    ``// Height of the tree``    ``int` `height;` `    ``// Root of biggest perfect sub-tree``    ``node rootTree;``};` `// Function to return the biggest``// perfect binary sub-tree``static` `returnType findPerfectBinaryTree(node root)``{` `    ``// Declaring returnType that``    ``// needs to be returned``    ``returnType rt = ``new` `returnType();` `    ``// If root is null then it is considered as``    ``// perfect binary tree of height 0``    ``if` `(root == ``null``)``    ``{``        ``rt.isPerfect = ``true``;``        ``rt.height = ``0``;``        ``rt.rootTree = ``null``;``        ``return` `rt;``    ``}` `    ``// Recursive call for left and right child``    ``returnType lv = findPerfectBinaryTree(root.left);``    ``returnType rv = findPerfectBinaryTree(root.right);` `    ``// If both left and right sub-trees are perfect and``    ``// there height is also same then sub-tree root``    ``// is also perfect binary subtree with height``    ``// plus one of its child sub-trees``    ``if` `(lv.isPerfect && rv.isPerfect &&``        ``lv.height == rv.height)``    ``{``        ``rt.height = lv.height + ``1``;``        ``rt.isPerfect = ``true``;``        ``rt.rootTree = root;``        ``return` `rt;``    ``}` `    ``// Else this sub-tree cannot be a perfect binary tree``    ``// and simply return the biggest sized perfect sub-tree``    ``// found till now in the left or right sub-trees``    ``rt.isPerfect = ``false``;``    ``rt.height = Math.max(lv.height, rv.height);``    ``rt.rootTree = (lv.height > rv.height ?``                             ``lv.rootTree : rv.rootTree);``    ``return` `rt;``}` `// Function to print the``// inorder traversal of the tree``static` `void` `inorderPrint(node root)``{``    ``if` `(root != ``null``)``    ``{``        ``inorderPrint(root.left);``        ``System.out.print(root.data + ``" "``);``        ``inorderPrint(root.right);``    ``}``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``// Create tree``    ``node root = newNode(``1``);``    ``root.left = newNode(``2``);``    ``root.right = newNode(``3``);``    ``root.left.left = newNode(``4``);``    ``root.left.right = newNode(``5``);``    ``root.right.left = newNode(``6``);` `    ``// Get the biggest sizes perfect binary sub-tree``    ``returnType ans = findPerfectBinaryTree(root);` `    ``// Height of the found sub-tree``    ``int` `h = ans.height;` `    ``System.out.println(``"Size : "` `+``                      ``(Math.pow(``2``, h) - ``1``));` `    ``// Print the inorder traversal of the found sub-tree``    ``System.out.print(``"Inorder Traversal : "``);``    ``inorderPrint(ans.rootTree);``}``}` `// This code is contributed by 29AjayKumar`

## Python3

 `# Python3 implementation of above approach` `# Tree node``class` `Node:``    ``def` `__init__(``self``, data):``        ``self``.data ``=` `data``        ``self``.left ``=` `None``        ``self``.right ``=` `None` `# To create a new node``def` `newNode(data):` `    ``node ``=` `Node(``0``)``    ``node.data ``=` `data``    ``node.left ``=` `None``    ``node.right ``=` `None``    ``return` `node` `# Structure for return type of``# function findPerfectBinaryTree``class` `returnType:` `    ``def` `__init__(``self``):``        ` `        ``# To store if sub-tree is perfect or not``        ``isPerfect ``=` `0` `        ``# Height of the tree``        ``height ``=` `0` `        ``# Root of biggest perfect sub-tree``        ``rootTree ``=` `0` `# Function to return the biggest``# perfect binary sub-tree``def` `findPerfectBinaryTree(root):` `    ``# Declaring returnType that``    ``# needs to be returned``    ``rt ``=` `returnType()` `    ``# If root is None then it is considered as``    ``# perfect binary tree of height 0``    ``if` `(root ``=``=` `None``) :``        ``rt.isPerfect ``=` `True``        ``rt.height ``=` `0``        ``rt.rootTree ``=` `None``        ``return` `rt``    ` `    ``# Recursive call for left and right child``    ``lv ``=` `findPerfectBinaryTree(root.left)``    ``rv ``=` `findPerfectBinaryTree(root.right)` `    ``# If both left and right sub-trees are perfect and``    ``# there height is also same then sub-tree root``    ``# is also perfect binary subtree with height``    ``# plus one of its child sub-trees``    ``if` `(lv.isPerfect ``and` `rv.isPerfect ``and``        ``lv.height ``=``=` `rv.height) :``        ``rt.height ``=` `lv.height ``+` `1``        ``rt.isPerfect ``=` `True``        ``rt.rootTree ``=` `root``        ``return` `rt``    ` `    ``# Else this sub-tree cannot be a perfect binary tree``    ``# and simply return the biggest sized perfect sub-tree``    ``# found till now in the left or right sub-trees``    ``rt.isPerfect ``=` `False``    ``rt.height ``=` `max``(lv.height, rv.height)``    ``if` `(lv.height > rv.height ):``        ``rt.rootTree ``=` `lv.rootTree``    ``else` `:``        ``rt.rootTree ``=` `rv.rootTree``    ``return` `rt` `# Function to print the inorder traversal of the tree``def` `inorderPrint(root):` `    ``if` `(root !``=` `None``) :``        ``inorderPrint(root.left)``        ``print` `(root.data, end ``=` `" "``)``        ``inorderPrint(root.right)``    ` `# Driver code` `# Create tree``root ``=` `newNode(``1``)``root.left ``=` `newNode(``2``)``root.right ``=` `newNode(``3``)``root.left.left ``=` `newNode(``4``)``root.left.right ``=` `newNode(``5``)``root.right.left ``=` `newNode(``6``)` `# Get the biggest sizes perfect binary sub-tree``ans ``=` `findPerfectBinaryTree(root)` `# Height of the found sub-tree``h ``=` `ans.height` `print` `(``"Size : "` `, ``pow``(``2``, h) ``-` `1``)` `# Print the inorder traversal of the found sub-tree``print` `(``"Inorder Traversal : "``, end ``=` `" "``)``inorderPrint(ans.rootTree)` `# This code is contributed by Arnab Kundu`

## C#

 `// C# implementation of the approach``using` `System;` `class` `GFG``{``    ` `// Node structure of the tree``public` `class` `node``{``    ``public` `int` `data;``    ``public` `node left;``    ``public` `node right;``};` `// To create a new node``static` `node newNode(``int` `data)``{``    ``node node = ``new` `node();``    ``node.data = data;``    ``node.left = ``null``;``    ``node.right = ``null``;``    ``return` `node;``}` `// Structure for return type of``// function findPerfectBinaryTree``public` `class` `returnType``{` `    ``// To store if sub-tree is perfect or not``    ``public` `bool` `isPerfect;` `    ``// Height of the tree``    ``public` `int` `height;` `    ``// Root of biggest perfect sub-tree``    ``public` `node rootTree;``};` `// Function to return the biggest``// perfect binary sub-tree``static` `returnType findPerfectBinaryTree(node root)``{` `    ``// Declaring returnType that``    ``// needs to be returned``    ``returnType rt = ``new` `returnType();` `    ``// If root is null then it is considered as``    ``// perfect binary tree of height 0``    ``if` `(root == ``null``)``    ``{``        ``rt.isPerfect = ``true``;``        ``rt.height = 0;``        ``rt.rootTree = ``null``;``        ``return` `rt;``    ``}` `    ``// Recursive call for left and right child``    ``returnType lv = findPerfectBinaryTree(root.left);``    ``returnType rv = findPerfectBinaryTree(root.right);` `    ``// If both left and right sub-trees are perfect and``    ``// there height is also same then sub-tree root``    ``// is also perfect binary subtree with height``    ``// plus one of its child sub-trees``    ``if` `(lv.isPerfect && rv.isPerfect &&``        ``lv.height == rv.height)``    ``{``        ``rt.height = lv.height + 1;``        ``rt.isPerfect = ``true``;``        ``rt.rootTree = root;``        ``return` `rt;``    ``}` `    ``// Else this sub-tree cannot be a perfect binary tree``    ``// and simply return the biggest sized perfect sub-tree``    ``// found till now in the left or right sub-trees``    ``rt.isPerfect = ``false``;``    ``rt.height = Math.Max(lv.height, rv.height);``    ``rt.rootTree = (lv.height > rv.height ?``                             ``lv.rootTree : rv.rootTree);``    ``return` `rt;``}` `// Function to print the``// inorder traversal of the tree``static` `void` `inorderPrint(node root)``{``    ``if` `(root != ``null``)``    ``{``        ``inorderPrint(root.left);``        ``Console.Write(root.data + ``" "``);``        ``inorderPrint(root.right);``    ``}``}` `// Driver code``public` `static` `void` `Main(String[] args)``{``    ``// Create tree``    ``node root = newNode(1);``    ``root.left = newNode(2);``    ``root.right = newNode(3);``    ``root.left.left = newNode(4);``    ``root.left.right = newNode(5);``    ``root.right.left = newNode(6);` `    ``// Get the biggest sizes perfect binary sub-tree``    ``returnType ans = findPerfectBinaryTree(root);` `    ``// Height of the found sub-tree``    ``int` `h = ans.height;` `    ``Console.WriteLine(``"Size : "` `+``                     ``(Math.Pow(2, h) - 1));` `    ``// Print the inorder traversal of the found sub-tree``    ``Console.Write(``"Inorder Traversal : "``);``    ``inorderPrint(ans.rootTree);``}``}` `// This code is contributed by Princi Singh`

## Javascript

 ``

Output:

```Size : 3
Inorder Traversal : 4 2 5```

Time Complexity: O(n)
We are traversing the entire tree once.

Space Complexity: O(h)
For a given tree, we are storing the height of the tree in the returnType.

My Personal Notes arrow_drop_up