Tree - path sum - java

Question -> Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
My Solution ->
public class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if (root == null || sum == 0){
return false;
}
List<Integer> resultSet = new ArrayList<Integer>();
Integer result = root.val;
inorder(root, result, resultSet);
return resultSet.contains(sum);
}
public void inorder(TreeNode root, Integer result, List<Integer> resultSet){
if (root.left == null && root.right == null){
resultSet.add(result);
}
if (root.left != null) {
result += Integer.valueOf(root.left.val);
inorder(root.left, result, resultSet);
}
if (root.right != null) {
result += Integer.valueOf(root.right.val);
inorder(root.right, result, resultSet);
}
}
}
Output ->
Input:
[1,-2,-3,1,3,-2,null,-1]
3
Output: true
Expected: false
I am really not sure where I am going wrong with this. I tried playing with the int and Integer type options for result , but it didn't work. Please help.

The problem I see is with result variable as once you add the value of left node to the result and are done with the left subtree then u will add the value of right child to the result, which is wrong as now it is has the sum of both left and right child value.
So essentially you are adding the values of all the nodes in the result that come before
the node root in the inorder traversal.
Can you try this:
public void inorder(TreeNode root, Integer result, List<Integer> resultSet){
if (root.left == null && root.right == null){
resultSet.add(result);
}
if (root.left != null) {
inorder(root.left, result+Integer.valueOf(root.left.val), resultSet);
}
if (root.right != null) {
inorder(root.right, result+Integer.valueOf(root.right.val), resultSet);
}
}
EDIT:1
Another simple approach to solve this problem: You don't need to create a array which contains the sum of all the root to leaf paths. You can simply keep decrementing the required sum.
Code:
public boolean hasPathSum(TreeNode root, int sum) {
if (root == null) {
return false;
} else {
return hasPathSumHelper(root, sum);
}
}
boolean hasPathSumHelper(TreeNode root, int sum) {
if (root.left == null && root.right == null) {//if leaf node
if (Integer.valueOf(root.val) == sum) { //if node value is equal to sum
return true;
} else {
return false;
}
}
if ((root.left != null) && (root.right != null)) {
return (hasPathSumHelper(root.left, sum - Integer.valueOf(root.val)) || hasPathSumHelper(root.right, sum - Integer.valueOf(root.val)));
}
if (root.left != null) {
return hasPathSumHelper(root.left, sum - Integer.valueOf(root.val));
} else {
return hasPathSumHelper(root.right, sum - Integer.valueOf(root.val));
}
}

Related

Binary Search Tree, Height Method not returning correct values

Java Binary Search trees, Height method not returning the correct height. I tried a lot of stuff on the internet, none of it worked. If someone can point out the issue with my code it will be very helpful.
#Override
public int height()
{
return heightRecursive(root);
}
private int heightRecursive(Node node) {
if(node == null || (node.right == null && node.right == null)) return 0;
int lh=0;
int rh=0;
if(node.left!=null) {
lh=heightRecursive(node.left);
System.out.println(lh);
}
if(node.right!=null) {
rh=heightRecursive(node.right);
}
//System.out.println("--------"+1+Math.max(lh, rh));
return 1+Math.max(lh, rh);
}
The Add() Method is below:
#Override
public boolean add(Comparable e)
{
addR(e,root);
return true;
}
public Node addR(Comparable e,Node n)
{
//System.out.println("Null --"+n+" "+e+" "+size);
if(n==null)
{
n=new Node(e);
size++;
System.out.println("final --"+n+" "+e+" "+size);
}
else if(e.compareTo(n.value)<0)
{
n.left = addR(e,n.left);
//size++;
}
else if(e.compareTo(n.value)>0)
{
n.right = addR(e,n.right);
//size++;
}
return n;
}
I can't seem to get to the root cause of this, after inputting the debug printline code in add method, this is the output:
A final --trees.SimpleTreeSet$Node#58c1670b A 1
B final --trees.SimpleTreeSet$Node#6b57696f B 2
R final --trees.SimpleTreeSet$Node#44c8afef R 1
W final --trees.SimpleTreeSet$Node#12f41634 W 1
O final --trees.SimpleTreeSet$Node#262b2c86 O 1
final --trees.SimpleTreeSet$Node#5ed828d A 1
Y final --trees.SimpleTreeSet$Node#7a3d45bd Y 1
The main problem is in your add method: the root will never change. So if you add a first node to an empty tree, that new node is lost: it is returned by addR, but your code ignores it.
So:
public boolean add(Comparable e)
{
root = addR(e,root);
return true;
}
Another problem concerns the base case of the height recursion:
if(node == null || (node.right == null && node.right == null)) return 0;
You should check node.left (not twice node.right) and also distinguish between a null and a node. There is a height difference between those two cases. When a single-node-tree has height 0, then an empty tree should have height -1.
Corrected:
if (node == null) return -1;
if (node.left == null && node.right == null)) return 0;

Check that sum of left and right children values equal value of the parent in Binary Trees?

I'm writing a method for a homework problem on binary trees.
Objective:
Given a binary tree, check if the tree satisfies the property that for each node, the sum of the values of its left and right children are equal to the node's value. If a node has only one child, then the node should have the same value as that child. Leaf nodes automatically satisfy the property.
I am getting an error that my code is not correct for all cases. For example if I have a tree
15
/ \
5 10
I am returning false when it should be true.
Here is my method so far, what am I doing wrong?
boolean BTchecksum(BinNode root) {
if (root == null || root.left() == null && root.right() == null) {return true;}
BinNode leftNode = root.left();
BinNode rightNode = root.right();
int sum = (int)(leftNode.element()) + (int)(leftNode.element());
int value = (int)(root.element());
return (sum == value) && BTchecksum(root.left()) && BTchecksum(root.right());
}
You wrote sum as:
leftNode.element()) + (int)(leftNode.element)));
Should be this:
leftNode.element()) + (int)(rightNode.element)));
Right now, you're probably getting null pointer exceptions because you're referencing children that may be null. This may not be the most efficient solution, but it takes care of all the cases.
public boolean BTchecksum(BinNode root) {
if (root == null || root.right()==null && root.left()==null) {
return true;
}
if (root.right() == null) {
return (root.left().value() == root.value())
&& BTchecksum(root.left());
} else if (root.left() == null) {
return (root.right().value() == root.value())
&& BTchecksum(root.right());
} else {
return (root.value() == root.left().value() + root.right().value())
&& BTchecksum(root.left()) && BTchecksum(root.right());
}
Revision (no NullPinterException)
public boolean BTchecksum(BinNode root)
{
if (root == null || root.left() == null && root.right() == null) {return true;}
int sum = 0;
if (root.left() != null){sum = sum + root.left().value();}
if (root.right() != null){sum = sum + root.right().value();}
return (sum == root.value()) && BTchecksum(root.left()) && BTchecksum(root.right());
}

Check if a binary tree is full in Java?

I am trying to write a method that will return true if a binary tree is full (each node has 2 child nodes or none) and false otherwise. This is working some of the time but not all. Any suggestions about where I am going wrong?
public static void testNum4()
{
System.out.println("How many nodes do you want in your tree?");
int num=sc.nextInt();
//TreeNode<Integer> root = TreeUtil.createBalancedNumberTree(num); Use to test for a balanced tree
TreeNode<Integer> root = TreeUtil.createIntegerTree(num);
TreeUtil.displayTreeInWindow(root);
System.out.println(isFull(root));
TreeUtil.displayTreeInWindow (root);
}
public static boolean isFull(TreeNode<Integer> root) {
// pre: root of tree, 0 or more nodes
// post: returns true if the input tree is a full tree; false otherwise
if (root!=null) {
if ((root.getLeft() != null && root.getRight() != null) || (root.getRight() == null && root.getLeft() == null))
{
return true;
}
else if (root.getLeft()!=null)
{
isFull(root.getLeft());
}
else if (root.getRight()!=null)
{
isFull(root.getRight());
}
else
return false;
}
return false;
}
Definition: a binary tree T is full if each node is either a leaf or possesses exactly two child nodes.
public static boolean isFull(TreeNode<Integer> root)
// pre: root of tree, 0 or more nodes
// post: returns true if the input tree is a full tree; false otherwise
{
if (root!=null)
{
if(root.getRight() == null && root.getLeft() == null)
{
return true;
}
if ((root.getRight() != null && root.getLeft() != null))
{
return isFull(root.getLeft())&&isFull(root.getLeft());
}
}
return false;
}
Try to add return to each statement.
else if (root.getLeft()!=null && root.getRight()!=null)
{
return isFull(root.getLeft()) && isFull(root.getRight());
}
Also, if the root node is null, then your tree is full. So the last return should be return true;
The problem is the else if and lack of return statements. Also no need to checking for null so much, and use of a method makes it more readable.
public static boolean isFull(TreeNode<Integer> node) {
if (node == null) return false;
if (isLeaf(node)) return true;
return isFull(node.getLeft()) && isFull(node.getRight());
}
public static boolean isLeaf(TreeNode<Integer> node) {
return node.getRight() == null && node.getLeft() == null;
}
You are not fully traversing the tree. Use recursion to hit all the nodes. Check the root node. If there are no children, return true. If there are children, make sure there are two, and then check each of them recursively.
I think that the if statements should be as follows:
if (root.getRight() == null && root.getLeft() == null)
{
// The node has no children (full)
return true;
}
else if (root.getLeft() != null && root.getRight() != null)
{
// There are two children. Tree is only full if both sub trees are full
return isFull(root.getLeft()) && isFull(root.getRight());
}
else
{
// Only one child
return false;
}
All the algoritms above return true in this case (as they shouldn't):
complete binary tree
. So, hope this helps:
//-1 means "false"
public boolean full() {
int high = 0;
return ( root != null && isFull(root, high) != -1 );
}
public boolean isLeaf() {
return node.getRight() == null && node.getLeft() == null;
}
private int isFull(TreeNode<T> node, int high)
{
++high;
if (node.isLeaf())
return high;
else
{
int hLeft=0, hRight=0;
if(node.getLeft() != null)
hLeft = isFull(node.getLeft(), high);
if(node.getRight() != null)
hRight = isFull(node.getRight, high);
if ( (hLeft == hRight) && (hLeft != -1) )
return ++high;
return -1;
}
}

Why are we checking for n.parent == null?

I am finding the 'next' node (i.e., in-order successor) of a given node in a binary search tree.
Why is this condition used in the code given below:
if (n.parent == null || n.right != null)
My question is: Why are we checking for n.parent == null ?
Full Code:
public static TreeNode inorderSucc(TreeNode n) {
if (n == null) return null;
// Found right children -> return left most node of right subtree
if (n.parent == null || n.right != null) {
return leftMostChild(n.right);
} else {
TreeNode q = n;
TreeNode x = q.parent;
// Go up until we’re on left instead of right
while (x != null && x.left != q) {
q = x;
x = x.parent;
}
return x;
}
}
public static TreeNode leftMostChild(TreeNode n) {
if (n == null) {
return null;
}
while (n.left != null) {
n = n.left;
}
return n;
}
if (n.parent == null || n.right != null)
Checking if n is the root node and it has a right subtree.

Searching in Pre Order Traversal way

I have a binary search tree. I know how to search using the search property. But my task is to search the tree without using search property.(Say, search in binary tree) This is how I have to search.
1. If you find the value in the current node return it.
2. else search in right. If not found in right, then search in left
3. If not found in the whole tree return null.
This is what i tried.
public Node search(int val)
{
Node target = this;
if(target.getVal() == val)
return this;
else if(target.getRight() == null && target.getLeft() == null)
return null;
if(target.getRight() != null)
{
return target.getRight().search(id);
}
if(target.getLeft() != null)
{
return target.getLeft().search(id);
}
return null;
}
Problem with my code is, if right child exists and val is not found in right I'm getting null value. (Not searching in left). How to resolve this?
public Node search(int val)
{
Node target = this;
if(target.getVal() == val)
return this;
else if(target.getRight() == null && target.getLeft() == null)
return null;
if(target.getRight() != null)
{
return target.getRight().search(id); //here lies the problem
}
if(target.getLeft() != null)
{
return target.getLeft().search(id);
}
return null;
}
The problem in your code is that you are returning the result of search in right subtree of the node being searched.
Here's the updated code
public Node search(int val)
{
Node target = null;
if(this.getVal() == val)
{
return this;
}
else if(this.getRight() == null && this.getLeft() == null)
return target;
if(this.getRight() != null)
{
target = this.getRight().search(id);
}
if(target==null && this.getLeft() != null)
{
target = this.getLeft().search(id);
}
return target;
}
This is untested code, but I'd change your logic a bit:
public Node search(int val)
{
if(this.getVal() == val)
return this;
if (this.getRight() != null) {
Node right = this.getRight().search(id);
if (right != null)
return right;
}
if (this.getLeft() != null) {
Node left = this.getLeft().search(id);
if (left != null)
return left;
}
return null;
}
In your version you are returning a solution with the sole requirement that the node on the right or left is not null. You have to return a solution only if a solution is found.

Categories

Resources