Welcome to DAY 56. Today we will diverge once again into the Data Structure Trees and look at some more traversals. I suggest reading the previous article on Trees before reading this.
Questions:
Maximum Depth of Binary Tree:
Given the root of a binary tree, return its maximum depth.
A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
Example 1:
- Input: root = [3,9,20,null,null,15,7]
- Output: 3
Algorithm and Code:
- So the question is basically asking us to find the height of binary tree.
- What's the height of a binary tree? It is the maximum level you can go to in the furthest leaf node.
- In our example we see 15 and 7 are the farthest from the root node.
- They are both at a height of 3.
- So We look at this in a recursive way, We don't need to find out the totalHeight. We can just find the max height bw Left and Right subtree and we can add 1 to that as the final node is root node.
- If you imagine this we can apply similar logic to left subtree's left subtree and so on and similarly for right subtree.
- Hence by using this logic we can find out max depth using this recursive approach.
int maxDepth(TreeNode* root) { if(root == NULL) { return 0; } int lh = maxDepth(root->left); int rh = maxDepth(root->right); return 1 + max(lh,rh); }
Question: Balanced Binary Tree
Given a binary tree, determine if it is height-balanced
A height-balanced binary tree is a binary tree in which the depth of the two subtrees of every node never differs by more than one.
Example 1:
- Input: root = [3,9,20,null,null,15,7]
- Output: true
Naïve Approach:
- We can either checkout the height at every node of the tree.
- If we find the absolute difference to be greater than 1 we return false.
- We use the code above to find the height of the subtrees and then We recursively check to find if each node is balanced.
- This is a good approach but we are taking a Time Complexity of O(n^2) to find our result as we are finding height in o(N) time for every node and traversing every node also takes O(N) time.
- This approach is not time efficient.
Code:
int maxDepth(TreeNode* root) { if(root == NULL) { return 0; } int lh = maxDepth(root->left); int rh = maxDepth(root->right); return 1 + max(lh,rh); } bool isBalanced(TreeNode* root) { // base case if(root == NULL) { return true; } bool lb = isBalanced(root->left); bool rb = isBalanced(root->right); bool diff = abs(maxDepth(root->left) - maxDepth(root->right)) <= 1; if(lb && rb && diff) { return true; } else { return false; } }
Complexity Analysis:
Time: O(N^2)
Space: O(1)
Better Approach:
- Instead of returning a height from our getHeight function or maxDepth function.
- How about we instead only get height if they are balanced.
- In the maxDepth function we are traversing the whole array anyway using the same logic.
- When we are finding the heights of left and right subtree of the node, why not instead of continuing we simply keep returning -1 which indicates it's not balanced.
- It removes the redundancy and also helps us out by optimizing the time.
Code:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int maxDepth(TreeNode* root) { if(root == NULL) { return 0; } int lh = maxDepth(root->left); if(lh == -1) return -1; int rh = maxDepth(root->right); if(rh == -1) return -1; if(abs(rh - lh) > 1) return -1; return 1 + max(lh,rh); } bool isBalanced(TreeNode* root) { return maxDepth(root) != -1; } };
Complexity Analysis:
Time: O(N)
Space: O(1)
Top comments (0)