Related Articles
Find the largest Perfect Subtree in a given Binary Tree
• Difficulty Level : Medium
• Last Updated : 26 Dec, 2019

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
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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 Prefect 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 Prefect 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 Prefect 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`
Output:
```Size : 3
Inorder Traversal : 4 2 5
```

My Personal Notes arrow_drop_up