Valid Binary Tree - algorithm

/**
* 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 {
static class ReturnData {
public boolean isBST;
public int max;
public int min;
public ReturnData(boolean is, int mi, int ma) {
isBST = is;
min = mi;
max = ma;
}
}
public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
}
ReturnData res = check(root);
if (res == null) {
return true;
}
return res.isBST;
}
private ReturnData check(TreeNode node) {
if (node == null) {
return null;
}
int min = node.val;
int max = node.val;
ReturnData left = check(node.left);
ReturnData right = check(node.right);
if (left != null) {
min = Math.min(min, left.min);
max = Math.max(max, left.max);
}
if (right != null) {
min = Math.min(min, right.min);
max = Math.max(max, right.max);
}
boolean isBST = true;
if (left != null && (!left.isBST || left.min >= node.val)) {
isBST = false;
}
if (right != null && (!right.isBST || right.min <= node.val)) {
isBST = false;
}
return new ReturnData(isBST, min, max);
}
}
I want to ask a LeetCode question, Question 98.
The question wants me to write an algorithm to check whether the given tree is a valid binary tree, so I wrote like this:
I create a constructor to initialize the return type, which contains the current node's value, max, and min value of its subtree.
I want to use recursion to check the validation.
But it doesn't work, I also check the solution but I still don't know why this way didn't work.
Hope someone could give me a hint, thanks.

The problem is in this condition:
left.min >= node.val
You'll want to see whether the maximum in the left tree exceeds the current node's value, so:
left.max >= node.val

Related

Looking for correct recursive algorithm for Leetcode 112

I am working on Leet Code problem 112. Path Sum:
Given the root of a binary tree and an integer targetSum, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum.
A leaf is a node with no children.
I the code below trying to solve it, but apparently it isn't correct as I keep running into failed test cases.
/**
* 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 boolean hasPathSum(TreeNode root, int targetSum) {
if(root.left==null&&root.right==null&&targetSum-root.val ==0)
return true;
else{
if(root.right!= null){
hasPathSum(root.right, targetSum-root.val);
}
if(root.left!=null) {
hasPathSum(root.left, targetSum-root.val);
}
} return false;
}
}
What is wrong with this code?
You are not using the values returned by the recursive calls you make. In a verbose way, you could fix that part of your code as follows:
boolean result = false;
if (root.right != null) {
result = hasPathSum(root.right, targetSum - root.val);
}
if (!result && root.left != null) {
result = hasPathSum(root.left, targetSum - root.val);
}
return result;
It is more compact when you use more logical operators for that:
return root.right != null && hasPathSum(root.right, targetSum - root.val)
|| root.left != null && hasPathSum(root.left, targetSum - root.val);
It is not stated explicitly in the Leet Code challenge, but when calling this function on an empty tree, it should return false. So you should foresee the case where root is null.
The complete solution could look like this:
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
return root != null &&
( root.left == null && root.right == null && targetSum == root.val
|| root.right != null && hasPathSum(root.right, targetSum - root.val)
|| root.left != null && hasPathSum(root.left, targetSum - root.val)
);
}
}
Here is my recursive solution in javascript:
var hasPathSum = function(root, targetSum) {
if (root) {
if (!root.left && !root.right) {
return root.val === targetSum;
}
if (root.left) {
const isTherePath = hasPathSum(root.left, targetSum - root.val);
if (isTherePath) return true;
}
if (root.right) {
const isTherePath = hasPathSum(root.right, targetSum - root.val);
if (isTherePath) return true;
}
}
return false;
};

Insertion in BST

I was doing a problem on insertion. This is the right answer.
/*
Node is defined as
typedef struct node
{
int data;
node * left;
node * right;
}node;
*/
node * insert(node * root, int value)
{
if(root == NULL)
{
node *temp = new node();
temp->left = NULL;
temp->right = NULL;
temp->data = value;
root = temp;
return root;
}
if(value > root->data)
{
root->right = insert(root->right, value);
}
else
root->left = insert(root->left, value);
return root;
}
The only difference with the solution I made is that in the if/else statements I did not assign anything. This is my code.
Node is defined as
typedef struct node
{
int data;
node * left;
node * right;
}node;
*/
node * insert(node * root, int value)
{
if(root == NULL)
{
node *temp = new node();
temp->left = NULL;
temp->right = NULL;
temp->data = value;
root = temp;
return root;
}
if(value > root->data)
{
insert(root->right, value);
}
else
insert(root->left, value);
return root;
}
I am not sure I understand why this is necessary because basically calling this function recursively will find a right place for the node with the data value.
Then, I create node with right data and just insert it there.
I will leave a link to the problem. https://www.hackerrank.com/challenges/binary-search-tree-insertion
Thanks for help!

Algorithm to print the total sum of all the path

Giving you a binary tree which defined as follows:
public class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}
}
print the total sum of all the path, a path is defined as the line from the root node to any leaf node
For example:
4 5 6 7 8 10 # # # # 9
should return:
path1: 4 + 5 + 7
path2: 4 + 5 + 8 + 9
path3: 4 + 6 + 10
so the total path sum should be: path1 + path2 + path3
how can we solve the problem by using
recursive
non-recursive
I have find a solution by using non-recursive, but have some little problem about recursive method
Non-Recursive Method:
/**
* non-recursive
*/
public static int pathSum2(TreeNode root) {
int sum = 0;
if (root == null) {
return sum;
}
Queue<TreeNode> queueNode = new LinkedList<TreeNode>();
Queue<Integer> queueSum = new LinkedList<Integer>();
queueNode.add(root);
queueSum.add(root.val);
while (!queueNode.isEmpty()) {
TreeNode node = queueNode.poll();
int temp = queueSum.poll();
if (node.left == null && node.right == null) {
sum += temp;
}
if (node.left != null) {
queueNode.add(node.left);
queueSum.add(node.left.val + temp);
}
if (node.right != null) {
queueNode.add(node.right);
queueSum.add(node.right.val + temp);
}
}
return sum;
}
Recursive Method:
/**
* recursive
*/
public List<List<Integer>> pathSum(TreeNode root) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
helper(rst, new ArrayList<Integer>(), root);
return rst;
}
public void helper(List<List<Integer>> rst, ArrayList<Integer> list,
TreeNode root) {
if (root == null) {
return;
}
list.add(root.val);
if (root.left == null && root.right == null) {
rst.add(new ArrayList<Integer>(list));
}
helper(rst, list, root.left);
helper(rst, list, root.right);
list.remove(list.size() - 1);
}
but in this way, what I have output is all the path, what if I want to get the total sum of those path?
One way to get the answer is iterator the List> and get the answer but I think it's inefficient. How can we deal with this just in the helper() method because for the sum, java is just pass-by-value
I have find a solution by using recursive
/**
* recursive
*/
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<List<Integer>> rst = new ArrayList<List<Integer>>();
helper(rst, new ArrayList<Integer>(), root, sum);
return rst;
}
public void helper(List<List<Integer>> rst, ArrayList<Integer> list,
TreeNode root, int sum) {
if (root == null) {
return;
}
list.add(root.val);
if (root.left == null && root.right == null) {
rst.add(new ArrayList<Integer>(list));
}
helper(rst, list, root.left, sum - root.val);
helper(rst, list, root.right, sum - root.val);
list.remove(list.size() - 1);
}

minimum element of binary tree

I have implemented functions to find the max and min element of the binary tree. But I am getting the wrong output for it.
Function to find the maximum of the binary tree.
int FindMax(struct TreeNode *bt)
{
//get the maximum value of the binary tree...
int max;
//get the maximum of the left sub-tree.
int left;
//get the maximum of the right sub-tree.
int right;
//get the root of the current node.
int root;
if(bt!=NULL)
{
root=bt->data;
//Call the left tree recursively....
left=FindMax(bt->leftChild);
//Call the right tree recursively...
right=FindMax(bt->rightChild);
if(left > right)
{
max=left;
}
else
{
max=right;
}
if(max < root)
{
max=root;
}
}
return max;
}
Function to find the min of binary tree.
int FindMin(struct TreeNode *bt)
{
//get the minimum value of the binary tree...
int min;
//get the minimum of the left sub-tree.
int left;
//get the minimum of the right sub-tree.
int right;
//get the root of the current node.
int root;
if(bt!=NULL)
{
root=bt->data;
//Call the left tree recursively....
left=FindMin(bt->leftChild);
//Call the right tree recursively...
right=FindMin(bt->rightChild);
if(left < right)
{
min=left;
}
else
{
min=right;
}
if(min > root)
{
min=root;
}
}
return min;
}
Output :
The maximum of tree 32767
The minimum of tree 0
private int minElem(Node node) {
int min= node.element;
if(node.left != null) {
min = Math.min(min, minElem(node.left));
}
if(node.right != null) {
min = Math.min(min, minElem(node.right));
}
return min;
}
Recursive implementation of finding minimum value in a generic binary tree:
Here is the BinaryTreeNode class:
package binaryTrees;
public class BinaryTreeNode {
private int data;
private BinaryTreeNode left;
private BinaryTreeNode right;
private int max;
private int min;
public int getMax() {
return BinaryTreeOps.maxValue(this);
}
public int getMin() {
return BinaryTreeOps.minValue(this);
}
public BinaryTreeNode(){
}
public BinaryTreeNode(int data){
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public BinaryTreeNode getLeft() {
return left;
}
public void setLeft(BinaryTreeNode left) {
this.left = left;
}
public BinaryTreeNode getRight() {
return right;
}
public void setRight(BinaryTreeNode right) {
this.right = right;
}
}
Here is the BinaryTreeOps class with the minValue operation: The crux is to use a static variable min so that we reset the same static variable every time we find a value lower than the previous value. It returns zero if pass a null node. You can modify this behaviour as per you requirement.
package binaryTrees;
public class BinaryTreeOps {
private static int min;
public static int minValue(BinaryTreeNode node){
min=node.getData(); //imp step, since min is static it is init by 0
minValueHelper(node);
return min;
}
public static void minValueHelper(BinaryTreeNode node){
if(node==null)
return;
if(node.getData()<min)
min=node.getData();
if(node.getLeft()!=null && node.getLeft().getData()<min)
min=node.getLeft().getData();
if(node.getRight()!=null && node.getRight().getData()<min)
min=node.getRight().getData();
minValueHelper(node.getLeft());
minValueHelper(node.getRight());
}
}
The problem is that you allow the function to be called on an empty tree. If bt is NULL then you are going to return an uninitialised value for min, which it seems just happens to be 0.
I don't like how you actually search the entire tree. FindMin should be O(logN) (if your tree is balanced), not O(N). I suggest you don't call blindly. Instead, always follow the path that is guaranteed to lead to a minimum. As soon as you find that value, your recursion stops:
int FindMin( struct TreeNode *bt )
{
if( !bt)
return 0; // Only if the tree contains nothing at all
if( bt->leftChild )
return FindMin(bt->leftChild);
return bt->data;
}
It's that easy.
Notice that I don't go down the right branch, because that will always be larger than the current node.
One way to do it (in C) using recursion:
In main:
printf("maximum (not BST) is: %d\n", FindMax(root, root->x));
The Function:
int FindMax(node *root, int max)
{
if(root->x > max) max = root->x;
if(root->left != NULL)
max = FindMax(root->left, max);
if(root->right != NULL )
max = FindMax(root->right, max);
return max;
}
Notice that here you have to pass the original root value when you first call the function, and then everytime pass the current maximum. You do not go into the function for empty nodes, and you don't create any new variables in the function itself.
The implementation of "ravi ranjan" only in c:
in main:
printf("minimum (not BST) %d\n", FindMin(root));
the function:
int FindMin(node *root)
{
int min = root->x;
int tmp;
if(root->left != NULL)
{
tmp = FindMin(root->left);
min = (min < tmp) ? min : tmp;
}
if(root->right != NULL)
{
tmp = FindMin(root->right);
min = (min < tmp) ? min : tmp;
}
return min;
}
Notice here you do create a local variable (much like the passed value in the previous example) and you also need to create a tmp variable for ease of use and readability. (or define a minimum macro beforehand).

Traversing the Binary Search Tree

I was reading through Introduction to algorithms i came across this problem about In-order Traversal of binary search tree without using a stack or recursion. Hint says to assume that testing of pointers for equality is a legitimate operation.I'm stuck finding the solution to this problem. Please give me some direction. I'm not looking for the code. Just give me the right direction.
Exact duplicate here
No stack nor recursion means you have to use pointers. Not giving you code nor the exact answer, since you asked not to :)
Think about how to explore the tree without using recursion: what would you need to do? What pointer(s) do you need to keep? Can a tree node have a pointer to the parent?
Hope it helps.
We need a Threaded Binary Tree to do in-order Traversal without recursion / stack.
Wiki says 'A binary tree is threaded by making all right child pointers that would normally be null point to the inorder successor of the node, and all left child pointers that would normally be null point to the inorder predecessor of the node'
So you are given a normal Binary Tree , Convert it into a Threaded Binary Tree which can be done using Morris Traversal.
What you are going to do in Morris Traversal is to connect each node with its in-order successor. So while visiting a node ,Search for its in-order predecessor and let it be Pred.
then make Pred->right=Current node and we have to revert back the changes too. You can better refer this http://www.geeksforgeeks.org/archives/6358 for a great explanation.
Hello Parminder i have implemented your question in java.Please check it once
class InorderWithoutRecursion {
public static void morrisTraversal(TreeNode root) {
TreeNode current,pre;
if(root == null)
return;
current = root;
while(current != null){
if(current.left == null){
System.out.println(current.data);
current = current.right;
}
else {
/* Find the inorder predecessor of current */
pre = current.left;
while(pre.right != null && pre.right != current)
pre = pre.right;
/* Make current as right child of its inorder predecessor */
if(pre.right == null){
pre.right = current;
current = current.left;
}
/* Revert the changes made in if part to restore the original
tree i.e., fix the right child of predecssor */
else {
pre.right = null;
System.out.println(current.data);
current = current.right;
}
}
}
}
public static void main(String[] args) {
int[] nodes_flattened = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
TreeNode root = TreeNode.createMinimalBST(nodes_flattened);
morrisTraversal(root);
}
}
For TreeNode class below code will help you..
public class TreeNode {
public int data;
public TreeNode left;
public TreeNode right;
public TreeNode parent;
public TreeNode(int d) {
data = d;
}
public void setLeftChild(TreeNode left) {
this.left = left;
if (left != null) {
left.parent = this;
}
}
public void setRightChild(TreeNode right) {
this.right = right;
if (right != null) {
right.parent = this;
}
}
public void insertInOrder(int d) {
if (d <= data) {
if (left == null) {
setLeftChild(new TreeNode(d));
} else {
left.insertInOrder(d);
}
} else {
if (right == null) {
setRightChild(new TreeNode(d));
} else {
right.insertInOrder(d);
}
}
}
public boolean isBST() {
if (left != null) {
if (data < left.data || !left.isBST()) {
return false;
}
}
if (right != null) {
if (data >= right.data || !right.isBST()) {
return false;
}
}
return true;
}
public int height() {
int leftHeight = left != null ? left.height() : 0;
int rightHeight = right != null ? right.height() : 0;
return 1 + Math.max(leftHeight, rightHeight);
}
public TreeNode find(int d) {
if (d == data) {
return this;
} else if (d <= data) {
return left != null ? left.find(d) : null;
} else if (d > data) {
return right != null ? right.find(d) : null;
}
return null;
}
private static TreeNode createMinimalBST(int arr[], int start, int end){
if (end < start) {
return null;
}
int mid = (start + end) / 2;
TreeNode n = new TreeNode(arr[mid]);
n.setLeftChild(createMinimalBST(arr, start, mid - 1));
n.setRightChild(createMinimalBST(arr, mid + 1, end));
return n;
}
public static TreeNode createMinimalBST(int array[]) {
return createMinimalBST(array, 0, array.length - 1);
}
}

Resources