class Solution {
static ArrayList<Integer> leaves1 = new ArrayList<Integer>();
static ArrayList<Integer> leaves2 = new ArrayList<Integer>();
public boolean leafSimilar(TreeNode root1, TreeNode root2) {
if(root1.left == null && root1.right == null && root2.left == null && root2.right == null)
{
if(root1.val == root2.val)
return true;
else
return false;
}
leafmethod1(root1);
leafmethod2(root2);
if (leaves1.size() != leaves2.size())
return false;
for(int k=0;k<leaves1.size();k++)
{
if(leaves1.get(k) != leaves2.get(k))
return false;
}
return true;
}
public void leafmethod1(TreeNode root)
{
if(root!=null && root.left==null && root.right==null)
{
leaves1.add(root.val);
}
if(root!=null)
{
if(root.left != null)
{
leafmethod1(root.left);
}
if(root.right != null)
{
leafmethod1(root.right);
}
}
}
public void leafmethod2(TreeNode root)
{
if(root!=null && root.left == null && root.right == null)
{
leaves2.add(root.val);
}
if(root!=null)
{
if(root.left != null)
{
leafmethod2(root.left);
}
if(root.right != null)
{
leafmethod2(root.right);
}
}
}
}
This is the code I wrote. But it's not running for some particular case like eg; root1 = [1,2] and root2 = [2, 2]. It seemed to work for all other big cases but only in small cases like eg; root1 =[1] and root2 = [1] it's giving me wrong answer.
I don't know where I am going wrong. Kindly help.
Related
I am trying to implement a getHeight method that has a o(1) time complexity. To do this I am aiming to assign every node their own height and to return the height of the root with the getHeight method. To do this I need to update the height of the nodes everytime I add or remove.
Thus, I chose to do this:
private void updateHeight(Node node)
{
if (node == null)
{
return;
}
updateHeight(node.left);
updateHeight(node.right);
this.helpHeight(node);
}
private void helpHeight(Node node)
{
if (this.isLeaf(node))
{
node.height = 0;
}
else if (node.left == null)
{
node.height = node.right.height + 1;
}
else if (node.right == null)
{
node.height = node.left.height + 1;
}
else
{
node.height = 1 + max(node.left.height, node.right.height);
}
}
private int max(int height, int height2) {
if (height > height2)
{
return height;
}
else
{
return height2;
}
}
public int height()
{
return root.height + 1;
}
Then I will call the updateHeight(Node node) method with the root as the parameter. However, it's not working when I test it this way:
public static void main(String[] arg)
{
BST bst = new BST();
bst.add("a");
bst.add("b");
bst.add("c");
System.out.println(bst.height());
bst.remove("c");
System.out.println(bst.height());
}
It's returning 2, then 2.
Just in case, here is my add method:
public boolean add(E e) throws NullPointerException
{
if (e == null)
{
throw new NullPointerException("Error: Cannot add a null object to the tree.");
}
if (root == null)
{
root = new Node(e);
return true;
}
Node current = root;
while (current != null ) {
if (current.data.compareTo(e) > 0) {
//add in the left subtree
if (current.left == null ) {
current.left = new Node (e);
size++;
this.updateHeight(root);
return true;
}
else {
current = current.left;
}
}
else if (current.data.compareTo(e) < 0) {
//add in the right subtree
if (current.right == null ) {
size++;
this.updateHeight(root);
current.right = new Node(e);
return true;
}
else {
current = current.right;
}
}
else { //duplicate
return false;
}
}
//should never get to this line
return false;
}
I am sure this repeats something, but yet due to short time I have to ask you straight forward help.
How to convert Ternary (: and ?) operator into IF-ELSE statement in Java?
public Integer get(Integer index) {
if (first == null) {
return null;
}
MyNode curNode = first;
while (index >= 0) {
if (index == 0) {
return curNode == null ? null : curNode.getValue();
} else {
curNode = curNode == null ? null : curNode.getNext();
index--;
}
}
return null;
}
What I did tried, but it gave me wrong output (this is all about LinkedList) is modifying it to:
while (index >= 0) {
if (index == 0) {
// pre-modified -> return curNode == null ? null : curNode.getValue();
if (first == null) {
return null;
} else {
return curNode.getValue();
}
} else {
if (curNode != null) {
return curNode.getNext().getValue();
//return null;
} else {
return null;
}
// pre-modified -> curNode = curNode == null ? null : curNode.getNext();
// pre-modified -> index--;
}
}
In addition to that it was necessary also to fix part after else to:
else {
if (curNode != null) {
curNode = curNode.getNext();
index--;
//return null;
} else {
curNode = null;
}
// pre-modified -> curNode = curNode == null ? null : curNode.getNext();
// pre-modified -> index--;
}
Question solved.
I have written the following pseudocode for a removeNode() method while working with BST's:
If left is null
Replace n with n.right
Else if n.right is null
Replace n with n.left
Else
Find Predecessor of n
Copy data from predecessor to n
Recursively delete predecessor*
Not only do I want this method to delete or remove Nodes, but I also want it to return true if the deletion is successful.
This is what I have written so far, and I was wondering if anyone would have feedback, suggested changes, or tips to help me complete the method. I will also attach my whole program below this method.
private void removeNode(Node<E> n) {
if (n.left == null) {
replace(n, n.right);
} else if (n.right == null) {
replace(n, n.left);
} else {
//How do I find pred of n
//Copy data from pred to n
//Recursively delete pred
}
}
Here is the rest of my code:
import java.util.Random;
public class BinarySearchTree<E extends Comparable<? super E>> extends BinaryTree<E> {
public boolean contains(E item) {
return findNode(item, root) != null;
}
private Node<E> findNode(E item, Node<E> n) {
if (n == null || item == null) return null;
int result = item.compareTo(n.data);
if (result == 0) {
return n;
} else if (result > 0) {
return findNode(item, n.right);
} else {
return findNode(item, n.left);
}
}
public E max() {
Node<E> m = maxNode(root);
return (m != null) ? m.data : null;
}
private Node<E> maxNode(Node<E> n) {
if (n == null) return null;
if (n.right == null) return n;
return maxNode(n.right);
}
public E min() {
Node<E> m = minNode(root);
return (m != null) ? m.data : null;
}
private Node<E> minNode(Node<E> n) {
if (n == null) return null;
if (n.left == null) return n;
return minNode(n.left);
}
public E pred(E item) {
Node<E> n = findNode(item, root);
if (n == null) return null;
Node<E> pred = predNode(n);
return (pred != null) ? pred.data : null;
}
private Node<E> predNode(Node<E> n) {
assert n != null;
if (n.left != null) return maxNode(n.left);
Node<E> p = n.parent;
while (p != null && p.left == n) {
n = p;
p = p.parent;
}
return p;
}
public E succ(E item) {
Node<E> n = findNode(item, root);
if (n == null) return null;
Node<E> succ = succNode(n);
return (succ != null) ? succ.data : null;
}
private Node<E> succNode(Node<E> n) {
assert n != null;
if (n.right != null) return minNode(n.right);
Node<E> p = n.parent;
while (p != null && p.right == n) {
n = p;
p = p.parent;
}
return p;
}
public void add(E item) {
if (item == null) return;
if (root == null) {
root = new Node<>(item, null);
} else {
addNode(item, root);
}
}
private void addNode(E item, Node<E> n) {
assert item != null && n != null;
int result = item.compareTo(n.data);
if (result < 0) {
if (n.left == null) {
n.left = new Node<>(item, n);
} else {
addNode(item, n.left);
}
} else if (result > 0) {
if (n.right == null) {
n.right = new Node<>(item, n);
} else {
addNode(item, n.right);
}
} else {
return; // do not add duplicates
}
}
public boolean remove(E item) {
Node<E> n = findNode(item, root);
if (n == null) return false;
removeNode(n);
return true;
}
private void removeNode(Node<E> n) {
if (n.left == null) {
replace(n, n.right);
} else if (n.right == null) {
replace(n, n.left);
} else {
//How do I find pred of n
//Copy data from pred to n
//Recursively delete pred
}
}
private void replace(Node<E> n, Node<E> child) {
assert n != null;
Node<E> parent = n.parent;
if (parent == null) {
root = child;
} else if (parent.left == n) {
parent.left = child;
} else {
parent.right = child;
}
if (child != null) child.parent = parent;
}
public String toString() {
return inorder();
}
The code to remove an element is very straightforward.
Search for the node you want to remove.
Check if the node has children.
Case 1 - Has Only left child -> Replace current node with left child.
Case 2 - Has Only right child -> Replace current node with right child.
Case 3 - Has both children -> Find smallest element in right child subtree, replace current node with that node and then delete that node.
The Code can be implemented recursively as follows ->
BinarySearchTree.prototype.remove = function(data) {
var that = this;
var remove = function(node,data){
if(node.data === data){
if(!node.left && !node.right){
return null;
}
if(!node.left){
return node.right;
}
if(!node.right){
return node.left;
}
//2 children
var temp = that.findMin(node.right);
node.data = temp;
node.right = remove(node.right,temp);
}else if(data < node.data){
node.left = remove(node.left,data);
return node;
}else{
node.right = remove(node.right,data);
return node;
}
};
this.root = remove(this.root,data);
};
How do you count number of branches, in this case branches with even integers. Here's what I have so far. It seems to work for a couple of the cases.
public int evenBranches() {
return evenBranches(overallRoot);
}
private int evenBranches(IntTreeNode root) {
if (root == null) {
return 0;
}
int val = 0;
if (root.left != null) {
val += evenBranches(root.left);
} else if (root.right != null) {
val += evenBranches(root.right);
}
if (root.data % 2 == 0) {
return val + 1;
} else {
return val;
}
}
You can modify the evenBranches() method as below: I think It will cover all edge cases, If any testcase is left, let me know, I will fix it.
public int evenBranches() {
return evenBranches(overallRoot, 0);
}
private int evenBranches(IntTreeNode root, int count) {
if(root == null || (root.left == null && root.right == null)) {
return count;
}
if(root.data % 2 == 0) {
count++;
}
count += evenBranches(root.left, count);
count += evenBranches(root.right, count);
return count;
}
You may need to remove the else condition when checking the occurrences in right branch. Otherwise it will check only one side. eg:
private int evenBranches(IntTreeNode root) {
if (root == null) {
return 0;
}
int val = 0;
if (root.left != null) {
val += evenBranches(root.left);
}
if (root.right != null) {
val += evenBranches(root.right);
}
if (root.data % 2 == 0) {
return val + 1;
} else {
return val;
}
}
You can very well achieve the desired results by using a global variable, and applying BFS (breadth first search) on your tree, in this manner:
int evencount = 0; // global-var.
public int evenBranches() {
evenBranches(overallRoot);
return evencount;
}
private void evenBranches(IntTreeNode root) {
if(!root) return;
if( (root.left || root.right) && (root.data % 2 == 0)){
evencount++;
}
evenBranches(root.left);
evenBranches(root.right);
}
I am trying to implement leafCount() and nodeCount() to this recursive binary tree - program.
When testing it, these two methods (or the tests of them) throw AssertionError, so obviously they're not working as expected. I cannot figure out where I'm doing or thinking wrong. If someone could explain what I'm doing wrong or pinpoint the problem, I would be very grateful.
public class BSTrec {
BSTNode tree, parent, curr;
public BSTrec () {
tree = null; // the root of the tree
parent = null; // keeps track of the parent of the current node
curr = null; // help pointer to find a node or its place in the tree
}
public boolean isEmpty() {
return tree == null;
}
private boolean findNodeRec(String searchKey, BSTNode subtree, BSTNode subparent) {
if (subtree == null) { // base case 1: node not found
curr = null;
parent = subparent; // the logical parent for the value
return false;
}
else {
if (subtree.info.key.equals(searchKey)) {
curr = subtree; // update current to point to the node
parent = subparent; // update parent to point to its parent
return true;
}
else {
if (searchKey.compareTo(subtree.info.key) < 0) {
return findNodeRec(searchKey, subtree.left, subtree);
}
else {
return findNodeRec(searchKey, subtree.right, subtree);
}
}
}
}
public NodeInfo retrieveNode(String searchKey) {
if (findNodeRec(searchKey, tree, null)) return curr.info;
else return null;
}
public void addRec(String keyIn, BSTNode subtree, BSTNode subparent, boolean goLeft) {
if (tree == null) { // a first node will be the new root: base case 1
tree = new BSTNode(new NodeInfo(keyIn));
curr = tree;
parent = null;
}
else { // insertion in an existing tree
if (subtree == null) {
if (goLeft) {
subparent.left = new BSTNode(new NodeInfo(keyIn));
curr = subparent.left;
parent = subparent;
}
else { // the new node is to be a left child
subparent.right = new BSTNode(new NodeInfo(keyIn));
curr = subparent.right;
parent = subparent;
}
}
else {
if (keyIn.compareTo(subtree.info.key) < 0) {
addRec(keyIn, subtree.left, subtree, true);
}
else {
addRec(keyIn, subtree.right, subtree, false);
}
}
}
}
public void deleteNode(String searchKey) {
boolean found = findNodeRec(searchKey, tree, null);
if (!found) // the key is not in the tree
System.out.println("The key is not in the tree!");
else {
if ((curr.left == null) && (curr.right == null))
if (parent == null)
tree = null;
else
if (curr == parent.left) // delete a left child
parent.left = null;
else // delete a right child
parent.right = null;
else // delete a node with children, one or two
if ((curr.left != null) && (curr.right != null)) { // two children
BSTNode surrogateParent = curr;
BSTNode replacement = curr.left;
while (replacement.right != null) {
surrogateParent = replacement;
replacement = replacement.right;
}
curr.info = replacement.info; // the information is copied over
if (curr == surrogateParent) {
curr.left = replacement.left; // curr "adopts" the left
replacement = null;
}
else {
surrogateParent.right = replacement.left;
replacement = null;
}
} // End: if two children
else { // delete a node with one child
if (parent == null)
if (curr.left != null)
tree = curr.left;
else
tree = curr.right;
else
if (curr == parent.left)
if (curr.right == null)
parent.left = curr.left;
else
parent.left = curr.right;
else
if (curr.right == null)
parent.right = curr.left;
else
parent.right = curr.right;
}
curr = null;
}
}
public void inOrder(BSTNode root) {
if (root != null) {
inOrder(root.left); // process the left subtree
System.out.println(root.info.key); // process the node itself
inOrder(root.right); // process the right subtree
}
}
public void preOrder(BSTNode root) {
if (root != null) { // implicit base case: empty tree: do nothing
System.out.println(root.info.key); // process the node itself
preOrder(root.left); // process the left subtree
preOrder(root.right); // process the right subtree
}
}
public void postOrder(BSTNode root) {
if (root != null) { // implicit base case: empty tree: do nothing
postOrder(root.left); // process the left subtree
postOrder(root.right); // process the right subtree
System.out.println(root.info.key); // process the node itself
}
}
public int nodeCount() {
int count = 0;
if (tree == null) {
count = 0;
//throw new NullPointerException();
}
else {
if (tree.left != null) {
count = 1;
count += tree.left.nodeCount();
}
if (tree.right != null) {
count = 1;
count += tree.right.nodeCount();
}
}
return count;
}
public int leafCount() {
int count = 0;
if (tree == null) {
return 0;
}
if (tree != null && tree.left == null && tree.right==null) {
return 1;
}
else {
count += tree.left.leafCount();
count += tree.right.leafCount();
}
return count;
}
private class BSTNode {
NodeInfo info;
BSTNode left, right;
BSTNode() {
info = null;
left = null;
right = null;
}
public int leafCount() {
// TODO Auto-generated method stub
return 0;
}
public int nodeCount() {
// TODO Auto-generated method stub
return 0;
}
BSTNode(NodeInfo dataIn) {
info = dataIn;
left = null;
right = null;
}
BSTNode(NodeInfo dataIn, BSTNode l, BSTNode r) {
info = dataIn;
left = l;
right = r;
}
}
}
public class NodeInfo {
String key; // add other fields as needed!
NodeInfo() {
key = null;
}
NodeInfo(String keyIn) {
key = keyIn;
}
}
Your nodeCount logic has an error :
if (tree.left != null) {
count = 1;
count += tree.left.nodeCount();
}
if (tree.right != null) {
count = 1; // here you initialize the count, losing the count of the left sub-tree
count += tree.right.nodeCount();
}
Change to
if (tree.left != null || tree.right != null) {
count = 1;
if (tree.left != null) {
count += tree.left.nodeCount();
}
if (tree.right != null) {
count += tree.right.nodeCount();
}
}
In your leafCount you are missing some null checks, since it's possible one of the children is null :
if (tree != null && tree.left == null && tree.right==null) {
return 1;
} else {
if (tree.left != null) // added check
count += tree.left.leafCount();
if (tree.right != null) // added check
count += tree.right.leafCount();
}
In here:
public int leafCount() {
int count = 0;
if (tree == null) {
return 0;
}
if (tree != null && tree.left == null && tree.right==null) {
return 1;
}
else {
count += tree.left.leafCount();
count += tree.right.leafCount();
}
return count;
}
you're not allowing for the possibility that tree.left is non-null but tree.right is null. In that case, you'll try to execute
count += tree.right.leafCount();
which will throw a NullPointerException.
I think you should also rethink what you're doing with your instance fields curr and parent. These really should be local variables in whatever method you need to use them in. A tree doesn't have a "current" node in any meaningful sense.