Balanced binary tree returning true - java

I am trying to solve a question of the balanced binary tree.
Given a binary tree : [1,2,2,3,3,null,null,4,4]. Determine if it's a balanced tree or not.
And I had the solution:
public boolean isBalanced(TreeNode root) {
int height = heightCalculation(root);
if(height > 1) return false;
else
return true;
}
public int heightCalculation(TreeNode root){
if(root == null)
return 0;
int left_height = Integer.MIN_VALUE;
int right_height = Integer.MIN_VALUE;
left_height = heightCalculation(root.left);
right_height =heightCalculation(root.right);
return Math.abs(left_height - right_height);
}
The tree structure looks like:
1
/ \
2 2
/ \
3 3
/ \
4 4
It's returning true but the actual answer is false.
Can someone help me in fixing the issue ? I have kept the tree structure for your reference

The problem is that the heightCalculation function which is supposed to calculate the heights of right and left sub-trees and find the difference always returns 0. Following is the correct implementation for calculating the height of a binary tree:
int height(TreeNode node) {
if(node == null) {
return 0;
} else {
return 1 + Math.max(height(node.left), height(node.right));
}
}
Use the above function to find the heights of the sub trees and then calculate the difference.

Related

Finding minimum height of binary tree...code missing 1 minor edit to pass all test cases

I'm trying to find the minimum height of a tree. I modified my original algorithm for finding the max height of a tree (but this time, just using Math.min instead of Math.max).
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
if(root == null){return Integer.MAX_VALUE;}
if(root.left == null && root.right == null){return 1;}
int left = minDepth(root.left);
int right = minDepth(root.right);
return Math.min(left, right) + 1;
}
}
It was able to pass a normal tree, and the Integer.MAX_VALUE is there for the test case of
2
\
3
\
4
\
5
However, the code will NOT pass the test case of simply having an empty input "[]".
Is there any changes I can make to this code that will pass? I'm scratching my head and wondering if I should delete it and start from scratch. I feel very close, though.
LC Question: https://leetcode.com/problems/minimum-depth-of-binary-tree/
The problem in your code, is when the tree is skewed for example, it will return the minimum depth-value for subtree's it traversed so far.
if you consider the following tree:
2
\
3
\
4
\
5
it should return -2147483648.
carefully check the left and right subtree of root, which is 2,
left subtree depth value: Integer.MAX_VALUE (+1) = -2147483648
right subtree depth value: 4 (+1) = 5
now check next element which is 3,
minimum value found so far: -2147483648
right subtree depth value: 3 (+1) = 4
now check next element which is 4,
minimum value found so far: -2147483648
right subtree depth value: 2 (+1) = 3
and so on.. and at the end will come up with the minimum number we have found so far, which is -2147483648 or in case of 2147483647 when the tree is empty or null.
you need to change the logic in which case it should take minimum depth-value for maximum depth-ed node:
I wrote one solution for you, check if it works:
int min = Integer.MAX_VALUE;
public int minDepth(TreeNode root) {
if(root == null){
return 0; /* return 0 when the tree is empty */
}
/* visit each node in DFS manner, and found maximum depth-ed node possible */
minDepth(root, 0);
return min+1;
}
private void minDepth(TreeNode root, int count){
if(root == null){
return;
}else if(root.left == null && root.right == null){
/* replace the minimum value with maximum-depth node counter */
if(min > count){
min = count;
}
}else{
count += 1;
minDepth(root.left, count);
minDepth(root.right, count);
}

Finding min in Binary tree?

I'm trying to find the min for a binary tree, NOT binary search tree, but can't get the answer, code is below. Please tell me what is wrong.
Edit: So with the help of a poster, I was able to get the code working. I made code 1 to work, but I don' understand why in code 2, we need to check for Math.min again when in code 1 we didn't have to do that.
Code 1:
static int min = 0;
static public int findMinimumValue(Node root) {
min = root.data;
findMinimumValue(root, root.data);
return min;
}
static public int findMinimumValue(Node root, int x) {
if(root == null) {
return min;
} else {
if(root.data < min) {
min = root.data;
}
int left = findMinimumValue(root.left, x);
int right = findMinimumValue(root.right, x);
return min;
}
}
Code 2:
static public int findSecondMinimumValue(Node root) {
// min = root.data;
return findSecondMinimumValue(root, root.data);
}
static public int findSecondMinimumValue(Node root, int min) {
if(root == null) {
return min;
} else {
if(root.data < min) {
min = root.data;
}
int left = findSecondMinimumValue(root.left, min);
int right = findSecondMinimumValue(root.right, min);
return Math.min(left, right);
}
}
Step 1: Identify the problem
Follow through what all you have done in the code base. Let's make a binary tree:
5
/ \
2 1
Clearly the minimum is 1, right? So, follow through your code with this example.
public int findMinimumValue(TreeNode root) {
return findMinimumValue(root, root.val);
}
The root will be the starting point.
int left = findMinimumValue(root.left, min);
int right = findMinimumValue(root.right, min);
This is what each and every node will see (if it is not null). It's a recursive call to the left, then to the right after it has gone as left as it can.
finalMinimumValue(TreeNode(5), 5)
Calls the following:
int left = finalMinimumValue(TreeNode(2), 5);
int right = finalMinimumValue(TreeNode(1), 5)
finalMinimumValue(TreeNode(2), 5)
Calls the following:
int left = finalMinimumValue(null, 5);
int right = finalMinimumValue(null, 5)
finalMinimumValue(null, 5)
Does the following code:
return min;
What is min? min is, well, 5.
Does that make sense? We traversed over 2, yet still kept the min as 5.
Step 2: Fix the problem
We concluded in step 1 that it makes no sense for us to not update min if we are currently at a node that is not the minimum. So, let's update it before we recursively go down also.
public int findMinimumValue(TreeNode root) {
return findMinimumValue(root, root.val);
}
public int findMinimumValue(TreeNode root, int min) {
if (root == null) {
return min;
} else {
// update your min variable here by comparing it with the node you currently are at!
int left = findMinimumValue(root.left, min);
int right = findMinimumValue(root.right, min);
if (left < min) {
min = left;
}
if (right < min) {
min = right;
}
return min;
}
}
Step 3: Test the solution
Let's follow through with the same example. We are expecting it to say it is 1.
5
/ \
2 1
1: Compute left for the root node
Our Node's value is 5. Is 5 less than our Node's value (5)? No. So, don't update the min.
Next, call the left child, Node(2)
2: Compute the min to return for Node 2
Our Node's value is 2. Is 5 less than our Node's value (2)? Yes! So, update our min value.
Now min is 2.
Next, call the left child, null. Since its left child is null, we return min, which is 2.
Now, call the right child, null. Since its right child is null, we return min, which is 2.
Well, left equals 2, right equals 2. So, return 2!
3: Compute the min to return for Node 1
Our Node's value is 1. Is 5 less than our Node's value (1)? Yes! So update the min.
Now min is 1.
Next, call the left child, null. Since its left child is null, we return min, which is 1.
Now, call the right child, null. Since its right child is null, we return min, which is 1.
Well, left equals 1, right equals 1. So, return 1!
4: Compute the min to return for the root node.
The left returned us 2.
The right returned us 1.
Since 1 is less than 2, 1 is the answer.
It works!

Finding number of routes that add up to a sum in a binary tree

You are given a binary tree in which each node contains an integer value.
Find the number of paths that sum to a given value.
The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
10
/ \
5 -3
/ \ \
3 2 11
/ \ \
3 -2 1
Return 3. The paths that sum to 8 are:
1. 5 -> 3
2. 5 -> 2 -> 1
3. -3 -> 11
class Solution {
int count = 0;
public int pathSum(TreeNode root, int sum) {
if (root == null) return 0;
return helper(root, sum) + helper(root.left, sum) + helper(root.right, sum);
}
public int helper(TreeNode root,int sum) {
if(root == null) {
return 0;
} else {
sum -= root.val;
if(sum == 0) {
return 1 + pathSum(root.left,sum) + pathSum(root.right,sum);
} else {
return pathSum(root.left,sum) + pathSum(root.right,sum);
}
}
}
}
The answer is suppose to be three but my answer returns 4 and I don't know why.
You want to have two cases defined for your algorithm.
Case 1: You are searching for a path that may exist beneath the current node.
Case 2: You are searching for a path that includes the current node.
You can define pathSum() to follow case 1 and helper() to follow case 2. This way, you can use pathSum() to traverse the tree, and call helper() at any node to check for a valid path starting from that node.
public int pathSum(TreeNode root, int sum) {
if (root == null) return 0;
return pathSum(root.left, sum) + pathSum(root.right, sum) //Case 1: check for sum below current node
+ helper(root, sum); //Case 2: check for sum starting from current node
}
public int helper(TreeNode root, int sum) {
if (root == null) return 0;
sum -= root.val;
if (sum == 0) {
return 1; //if sum equals 0, we have a complete path, no need to go further
}
//else we do not have a complete path, continue searching in left and right child nodes
return helper(root.left, sum) + pathSum(root.right, sum);
}

How to fix a method that decides is tree a balanced tree or not?

For example, I have a tree:
8
_ _
/ \
1 48
/ / \
0 40 50
/
10
When I add 10 to the TREE, my method decides, that this AVL tree is not an AVL tree and tries to balance it. I don't understand why the isAVLTree method does not work.
public static boolean isAVLTree(Root root) {
return (findMaxDepth(root) - findMinDepth(root)) <= 1;
}
public static int findMaxDepth(Root root) {
if (root == null ) {
return 0;
}
return 1 + Math.max(findMaxDepth(root.leftSide), findMaxDepth(root.rightSide));
}
public static int findMinDepth(Root root) {
if (root == null) {
return 0;
}
return 1 + Math.min(findMinDepth(root.leftSide), findMinDepth(root.rightSide));
}
Сurrently the method isAVLTree returns false, because
(findMaxDepth(root) - findMinDepth(root)) <= 1
(( 4 - 2) <= 1 ) ->>>>>>>>>>>>>> FALSE
In an AVL tree, the heights of the two child subtrees of any node differ by at most one
(AVL Tree)
That's not what you implemented in your isAVLTree method. The difference between the max depth and min depth doesn't have to be <= 1.
Instead, you should require that both the left and right sub-trees are AVL trees, and in addition the difference between the heights of the left and right sub-trees <= 1.
public static boolean isAVLTree(Root root)
{
if (root == null) {
return true;
}
return Math.abs(findMaxDepth(root.leftSide) - findMaxDepth(root.rightSide)) <= 1 &&
isAVLTree (root.rightSide) &&
isAVLTree (root.leftSide);
}

Find sum of nodes height in a binary tree recursively

How to find sum of node's height in a binary tree recursively?
Example:
public int totalHeight() {
return totalHeight(root);
}
private int totalHeight(BinaryNode<AnyType> n) {
int totalHeight = 0;
if (n.left == null && n.right == null)
return totalHeight;
if (n.left != null && n.right != null)
return totalHeight + 1
+ Math.max(totalHeight(n.left), totalHeight(n.right));
if (n.left != null)
return totalHeight + 1 + Math.max(totalHeight(n.left), -1);
if (n.right != null)
return totalHeight + 1 + Math.max(-1, totalHeight(n.right));
return totalHeight;
}
I have tried this, but it only get the height of the tree instead of sum of all node's height.
I feel difficult to track the counter in recursion, it seems that the totalHeight set to 0 every recursive call. This is not good.
A simple version would be to do a two-pass process where you first record for each node the height it is at, and then iterate through the nodes to sum them up. This method can be made recursive, but it is easy to do it in just one pass by summing as you calculate the height.
public static int totalHeightSum = 0;
private int calculateHeightAndAdd ( Node n )
{
if ( n == null )
return 0;
int leftHeight = calculateHeightAndAdd ( n.left );
int rightHeight= calculateHeightAndAdd ( n.right);
int myHeight = 1 + Math.max ( leftHeight, rightHeight );
totalHeightSum += myHeight;
return myHeight;
}
Recurcively find height of each node and keep adding to a static variable. Alternately, you could memorize the height and store in each node and then do another recursion to add them up.
The recursion should return the height of the node n and not the total heights of each of the nodes in the subtree.
Given your implementation of the height of a node, let's simply call it height(BinaryNode<?>), you can:
if you have access to all the nodes in a collection:
int sumHeight(List<BinaryNode<?>> nodes) {
int sum = 0;
for (BinaryNode<?> node: nodes) {
sum += height(node);
}
return sum;
}
if you only have access to the nodes in a tree structure:
int sumHeight(BinaryNode<?> node) {
if (node == null) return 0;
return height(node) + sumHeight(node.left) + sumHeight(node.right);
}
It would be interesting to see if there're algo's that can do the calculation in one recursion (maybe some backtracking algo?).
Ok. I have come out a solution.
a) if n == null return 0
b) if n.left == null && n.right == null return 0
c) the total height is total height of left + total height of right + the height of it self
the height of itself is:
1) if left side is larger, then total height of left minus total height of left's left
2) if right side is larger, then total height of right minus total height of right's right
public int totalHeight() {
return totalHeight(root);
}
private int totalHeight(BinaryNode<AnyType> n) {
if (n == null)
return 0;
else if (n.left == null && n.right == null)
return 0;
else
return totalHeight(n.left)
+ totalHeight(n.right)
+ (totalHeight(n.left) > totalHeight(n.right) ? totalHeight(n.left)
- (n.left == null ? 0 : totalHeight(n.left.left))
: totalHeight(n.right)
- (n.right == null ? 0
: totalHeight(n.right.right))) + 1;
}
I am assuming you are not updating heights during insertion.
Solution:
I would traverse through the tree in a inorder way. So I first declare root.height=0.
And then say
BinaryNode right;
BinaryNode left;
BinaryNode parent;
static int level;
int height;
if(left!=null)
{
left.height=left.parent.height+1;
level=level+left.height;
left.yourMethod();
}
if(right!=null)
{
right.height= right.parent.height+1;
level=level+right.height;
right.yourMethod();
}
So you will now have level that stores all the heights.
Alternative method can be Breadth first search traversal using a queue, but the answer would be the same.
Hope this helps.
void addHeights(class tree* root, int depth, int& sum)
{
if(root)
{
addHeights(root->left, depth+1, sum);
addHeights(root->right, depth+1, sum);
sum += depth;
}
}
public int sum(){
return sum(root);
}
private int sum(BinaryNode <?> n){
if(n == null)
return 0;
else
return n.data + sum(n.left) + sum(n.right);
}
I need more data to assess your code though I am assuming that you called the data inside the node "data".
So if the node is null it means you have reached the end of the tree and returns 0. Otherwise it takes the data and traverses towards the left then to the right. With each recursion they are being added until they are no more nodes left to be added.
private int maxHeight(BinaryNode<AnyType> n) {
if (n ! = null) return 0;
int leftheight = maxHeight(n.left);
int rightheight = maxHeight(n.right);
return (leftheight > rightheight) ? leftheight + 1 : rightheight + 1;
}
So far you have known the 4 cases to count the height
The essence is to continue to go left or right node if the left child or the right child exist.
if exist, return 1.
The counting function goes in the last statement. That is to get the largest height counted.
The main course is to get familiar with recursion and the programming stack when the method is working.

Categories