convert binary tree to sum tree in Java - java

REFERENCE I am copy pasting the problem and the solution that works in C, I am not able to get this working in Java. I understand primarily it is because in Java parameters are passed by value and that is causing problem to maintain state of "old_value". But I even tried changing it to a custom MyInt with set and get, still not able to get this working. So, probably I am missing something else too here. Kindly suggest.
Given a Binary Tree where each node has positive and negative values.
Convert this to a tree where each node contains the sum of the left
and right sub trees in the original tree. The values of leaf nodes are
changed to 0.
For example, the following tree
10
/ \
-2 6
/ \ / \
8 -4 7 5
should be changed to
20(4-2+12+6)
/ \
4(8-4) 12(7+5)
/ \ / \
0 0 0 0
Code:
int toSumTree(struct node *node)
{
// Base case
if(node == NULL)
return 0;
// Store the old value
int old_val = node->data;
// Recursively call for left and right subtrees and store the sum as
// new value of this node
node->data = toSumTree(node->left) + toSumTree(node->right);
// Return the sum of values of nodes in left and right subtrees and
// old_value of this node
return node->data + old_val;
}
Java Code:
public static int sumTree(Node node){
if(node == null)
return 0;
MyInt old_value = new MyInt(node.data);
node.data = sumTree(node.left) + sumTree(node.right);
return node.data + old_value.getData();
}

I was running wrong tests. Same code logic will work in Java as well as rightly pointed out in comments that pass by value does not make a difference because value is getting returned. The following is the working Java Code:
public static int sumTree(TreeNode node){
if(node == null)
return 0;
int old_value = node.value;
node.value = sumTree(node.left) + sumTree(node.right);
return node.value + old_value;
}

Related

Recursive generator of random algebraic expressions tree issue

Problem description
I am trying to write a math test for my little son.
Such test must generate a list of random algebraic expressions according to certain rules and check the correctness of solution.
In particular, I want to generate expressions consisting strictly of a given number of operators that are selected from a certain list.
For example generate a list of expression consisting of 3 operators of addition and subtraction in random order like:
12 - (5 + 2) + 2
3 + 4 - 2 + 10
and so on
To represent and calculate the expression, I use the binary expression tree structure.
Each tree consists of either a Leaf or a Node that contains an Operator and two subtrees.
This is a simple recursive structure and I want to work with it only recursively.
No setters in the classes of the tree. I can only use constructors to create a tree.
Leaf class
public final class Leaf implements Expression {
private final int value;
public Leaf(int value) {
this.value = value;
}
// ...
}
Node Class
public final class Node implements Expression {
private final Operator operator;
private final Expression left;
private final Expression right;
public Node(#NotNull Operator operator,
#NotNull Expression left,
#NotNull Expression right) {
this.operator = operator;
this.left = left;
this.right = right;
}
// ...
}
And Operator is a simple Enum type. I simplify my classes for the purposes of this question.
My issue
I am trying to build an expression based on the following rules:
There should be at least one operator in the expression, so my tree always starts from the Node.
I choose a random operator from a given list and increase the number of operators used
While this number less than the given number of operators I construct the left and rights subtree for current Node.
The left subtree can be randomly either a Leaf or Node
The right subtree can also be either a Leaf or Node, but if the left subtree is a Leaf and there are still unused operators, then the right must be a Node.
I wrote such an expression builder:
public class SmartExpressionBuilder {
private final Random random = ThreadLocalRandom.current();
private final List<Operator> allowedOperators;
private final int numberOfOperators;
public SmartExpressionBuilder(List<Operator> allowedOperators, int numberOfOperators) {
this.allowedOperators = allowedOperators;
this.numberOfOperators = numberOfOperators;
}
private int operatorsUsed;
public Expression build() {
operatorsUsed = 0;
return helper();
}
private Expression helper() {
if (operatorsUsed == numberOfOperators) return randomLeaf();
Operator op = randomOperator();
Expression left = random.nextBoolean() ? helper() : randomLeaf();
Expression right = (left instanceof Leaf || random.nextBoolean()) ? helper() : randomLeaf();
return new Node(op, left, right);
}
private Operator randomOperator() {
operatorsUsed++;
return allowedOperators.get(random.nextInt(allowedOperators.size()));
}
private Leaf randomLeaf() {
return new Leaf(random.nextInt(1, 10));
}
public static void main(String[] args) {
final var builder = new SmartExpressionBuilder(List.of(Operator.ADD, Operator.SUB), 4);
IntStream.range(0, 10)
.mapToObj(ignored -> builder.build())
.forEach(exp -> {
System.out.printf("%s = %d%n", exp.infix(), exp.evaluate());
TreePrinter.print(exp);
});
}
}
This works in principle. In the sense that a tree really builds with a given number of operators.
But there's a problem.
I get nodes looks like this:
Node Node
/ \ or / \
Leaf Node Node Leaf
For example my actual expression and tree may looks like this:
4 + 4 - (1 + 3) - 2 = 2
+
4 -
- 2
4 +
1 3
but i never get tree like this:
Node +
/ \ or - +
Node Node 5 2 2 -
6 1
I understand what the essence of the problem is.
In my recursive function, I always go into the left tree first.
And every time my random generates an the Node is in the left subtree, and not the Leaf, recursion dive deeper and deeper int the left subtree until unused operators ends.
This means that if an Node appeared in the left subtree, then Node cannot appear in the right at the same depths of tree.
I broke my brain, but did not figure out how to solve this problem without abandoning the recursive construction of my tree.
I would be very grateful for any ideas how build nodes of this kind
Node
/ \
Node Node
It's going to be very difficult to get balanced trees this way - you have to tune it very carefully for the left tree to probably give you half the operators. I don't think it's worth it.
Instead, I would pick the target number of operators at the top level - that would be a minimum plus some random range to generate larger or smaller expressions - and then randomly assign some of them to each subtree. So you have a recursive call that takes a size parameter; if size==0, generate a leaf, otherwise make a node, and split size-1 into a leftSize and rightSize to pass to the recursive calls.
Here's some rough pseudocode (I don't write much Java these days, but hopefully it makes the algorithm clear)
private Expression build(int size){
if (size == 0) return buildLeaf()
else {
leftSize = randomInt(size-1)
rightSize = size - 1 - leftSize
leftTree = build(leftSize)
rightTree = build(rightSize)
return buildNode(leftTree, rightTree, getRandomOperator())
}
}
Does that make sense and work for you?
I rewritten my method, as Edward Peters suggested.
At each step of recursion, I randomly determine how many Node's will be in the left and right trees (the sum of these numbers at the first step should be equal to the required number of operators in the expression), and return the Leaf if the number of nodes turns out to zero.
It's work just fine.
public Expression build(int numberOfOperators) {
if (numberOfOperators == 0) return randomLeaf();
int leftNodes = random.nextInt(numberOfOperators);
int rightNodes = numberOfOperators - leftNodes - 1;
return new Node(randomOperator(), build(leftNodes), build(rightNodes));
}
One example of resulting expression tree:
5 + 5 - (4 + 7) = -1
- Node
+ + or Node Node
5 5 4 7 Leaf Leaf Leaf Leaf

Double-ended queue - mask integer

I'm having a hard time understanding what the mask integer is for (2nd line). I get that it regulates where values are placed in a double-ended queue, but I don't get how exactly. This is part of the code from a double-ended queue just to have some context.
public class DEQueue {
private int mask = (1 << 3) - 1;
private String[] es = new String[mask + 1];
private int head, tail;
public void addFirst(String e) {
es[head = (head - 1) & mask] = e;
if (tail == head) {
doubleCapacity();
}
}
public String pollFirst() {
String result = es[head];
es[head] = null;
if (tail != head) {
head = (head + 1) & mask;
}
return result;
}
public String peekFirst() {
return es[head];
}
public void addLast(String e) {
es[tail] = e;
tail = (tail + 1) & mask;
if (tail == head) {
doubleCapacity();
}
}
mask is used to wrap around the head and tail indices when new elements are added or removed. To be usable as bit mask, it is created by first shifting 1 a certain number of bits (here 3) and then performing - 1 to set all lower bits to 1.
In your example the initial value is (1 << 3) - 1, which is equivalent to binary 111. This represents an initial deque (double-ended queue) capacity of 8 (23) due to the 0 being used as index as well.
Now let's imagine for an empty deque addFirst(...) is called:
head is initially 0
head - 1 is -1, due to being in two's complement this is equivalent to binary 1...111 (all bits are 1)
Applying & mask works as bit mask and only selects the bits which have the value 1 in mask, that is the lowest three bits, here: 1...111 & 111. This wraps the -1 from the previous step to a 7 (binary 111).
In the end that means the addFirst(...) call caused head to wrap around and place the element at es[7], the last position in the array.
Now let's consider the similar situation of calling addLast(...) when tail already points to the last element of the array, assuming this index 7 here again. Note that in your implementation tail seems to point to the next free index at the end of the deque.
tail + 1 is 8, the binary representation is 1000
& mask again works as bit mask, 1000 & 111. It again only selects the lowest three bits, which are all 0 in this case. This effectively wraps the 8 to a 0, the first index in the array.
(The situation is the same for calls to pollFirst())
For all other calls to addFirst(...) and addLast(...) applying the bit mask & mask has no effect and leaves the indices unchanged because they are in range [0, array.length).

Validate a Binary Search Tree

I am working on a leetcode problem where I am asked to check whether or not a Binary Search Tree is valid. So far, my solution only passes 58 out 75 test cases. Any pointers on where I went wrong and how to fix it?
Here is the question:
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
Example 1:
2
/ \
1 3
Input: [2,1,3]
Output: true
Example 2:
5
/ \
1 4
/ \
3 6
Input: [5,1,4,null,null,3,6]
Output: false
Explanation: The root node's value is 5 but its right child's value is 4.
Here is my Solution:
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidHelper(root);
}
public boolean isValidHelper(TreeNode root)
{
if(root == null)
return true;
isValidHelper(root.left);
if(root.left != null && !(root.left.val < root.val) || root.right != null && !(root.right.val > root.val))
return false;
isValidHelper(root.right);
return true;
}
}
Your program fails in cases like this:
5
3 7
1 6
because you only compare the value at the root of the subtrees.
I don't give a fix on purpose. You will learn more finding that out yourself.

LCA of Binary Tree - Need some Advice

I know this question has been asked many times. I need some clarification on LCA of a Binary Tree (not BST). If I am trying to find LCA of two nodes(3,11) from the given tree :
_______1______
/ \
___2__ ___4__
/ \ / \
6 5 9 11
/ \
7 3
The Code returns 11 for (3,11).
// Binary Tree LCA not BST
private Node findLowestCommonAncestor(Node root, int value1, int value2) {
Node leftLCA = null;
Node rightLCA = null;
if (root == null) {
return null;
}
else {
int value = root.item;
if (value == value1 || value == value2) {
return root;
}
else {
leftLCA = findLowestCommonAncestor(root.left, value1, value2);
rightLCA = findLowestCommonAncestor(root.right, value1, value2);
if (leftLCA != null && rightLCA != null) {
return root;
}
return (leftLCA != null) ? leftLCA : rightLCA;
}
}
}
Here I am confused, It should be 4 right. Please correct me If I am wrong. Am I confusing here ? or Is it how LCA works ?
11 is the correct LCA of (3, 11) in the tree you've shown.
I think you've perhaps overlooked the bit in the definition of LCA where elements are considered descendants of themselves:
...the lowest common ancestor (LCA) of two nodes v and w in a tree or directed acyclic graph (DAG) is the lowest (i.e. deepest) node that has both v and w as descendants, where we define each node to be a descendant of itself (so if v has a direct connection from w, w is the lowest common ancestor).
(emphasis mine)
Since 3 is a child of 11, the LCA is 11.

How to compare ints stored in linked lists - Java

I'm looking for some advice on a Java assignment. What I'm asked to do is perform different operations on numbers that are stored in a linked list, with each digit in a separate node. The point is to write a program that can do arithmetic on numbers that are very very large.
The particular problem that I'm looking for help on is for writing a method that compares two numbers, similar to regular compareTo() method for ints. It should return -1 if this.num < num, +1 if this.num > num, and 0 if they are equal.
What's making this difficult for me is the fact that the assignment specifies that the linked lists should store the numbers in reverse order. For example, the linked list for the number 145 would look like:
5 => 4 => 1 => null
This makes it easier to add numbers together but it's making it a headache for me when trying to compare. Here's what I've come up with, the comments explain how it's supposed to work.
public int compareTo(LLNum list)
{ // Compares two numbers.
// If the two numbers are of a different length, clearly the shortest is the smallest.
// If the two numbers are of equal length, call traverseToCompare to do the comparison.
if (this.len > list.len)
{
compareResult = 1;
}
else if (this.len < list.len)
{
compareResult = -1;
}
else if (this.len == list.len)
{
traverseToCompare(this.head, list.head);
}
return compareResult;
}
public void traverseToCompare(ListNode node1, ListNode node2)
{ // In the case that both numbers are of the same length, recursively traverse the list.
// compare each digit individually while unwinding the stack.
// Once two digits are found to be different, break out of the unwinding (Note: I could not find a way of breaking out)
// Since the dominant digit is at the tail end, this ensures the least number of comparisons.
if (node1 == null || node2 == null)
{ // Base case. Handles the case where both numbers are identical.
compareResult = 0;
return;
}
traverseToCompare(node1.getNext(), node2.getNext());
if (node1.getItem() > node2.getItem())
{
compareResult = 1;
}
if (node1.getItem() < node2.getItem())
{
compareResult = -1;
}
return;
}
The numbers being in reverse order is what pulled me towards recursion. I thought I would recursively traverse the list and then compare each digit on the way out, and somehow break out of the recursion at the first digits that are not the same. I realize this is not a usual way to use recursion but I wasn't sure how else to do it. Is there a way I could break without just throwing an exception? I think that might be a little too sloppy. Or any suggestions on how to do this without recursion?
Please don't just give me some code to copy and paste. I'm just looking to be pointed in the right direction. Thanks!
If I had to do this I would first check the lengths of both lists (like you did). If they're equal, a better way to do the comparison would be to create an iterator for each list. You can then increment the iterators at the same time and compare the values at that position in the linked lists. Doing it this way, you can simply stop comparing the lists once you have determined that one contains a larger number than the other.
In traverseToCompare you will need to take care of some cases.
It will be better and clean if you do not use the recursion.
Following can be a solution
boolean areSame = true;
boolean digitDiffer = false;
int compareResult = 0;
int length = node1.length
for(int i=0; i<length; i++)
{
if(!digitDiffer && ((node1.getItem() == node2.getItem()))
{
continue
}
else
{
digitDiffer = true;
if(node1.getItem() >= node2.getItem())
{
compareResult = 1
}
else
{
compareResult = -1;
}
}
}
return compareResult;
The best way to do it is to traverse the list for each number and construct the number and then compare the 2 numbers.
The way to construct a number from the list would be
int i = 0
int f = 1
Do while GetNext() <> Null
i = i + GetCurrentItem() * f
f = f * 10
End Do
For eg. if the number is 145, then the list would have 5->4->1
So running the above code
i = 0
f = 1
i = i + 5*1 = 5
f = f * 10 = 10
i = i + 4*10 = 45
f = f * 10 = 100
i = i + 1*100 = 145
f = f * 10 = 1000
So it comes out with i = 145.
It would have been much easier to do using plain String; as you could store data of any length. But anyway the requirement is for LinkedList :
Now as the data is stored in revers order; this means you can't decide response of compareTo method until you go through the complete list, as most significant data is stored at last position.
5 --> 4 --> 1 == 145
1 --> 4 --> 5 == 541
So read through the whole least; then you can store the value in a String and then decide compareTo method result.
traverseToCompare method is called for same length items. So you can write your own algorithm to compare two numbers stored in String.
Edit
If String is not allowed
Then will suggest you to do the same thing manually; iterate through the whole list compare the last node, if last node is same then compare the previous node and so on...

Categories