Find least common ancestor of two nodes in java - java

I have looked at a lot of other answers on stackoverflow and can't find anything that works, I either get the root, or node1 itself returned, I'm not sure how to do this recursively and have tried it many times all ending the same way. Any help would be greatly appreciated!
Here's my code:
private static Node findLCA(Node node1, Node node2) {
Node temp1 = node1, temp2 = node2, currentLargest = null;
int largestDepth = 0;
boolean found = false;
if(node1 == null || node2 == null){
return null;
} else{
while(found == false){
if(temp1.getParent() != null && temp2.getParent() != null && temp1.getParent() == temp2.getParent() && nodeDepth(temp1.getParent()) > largestDepth){
largestDepth = nodeDepth(temp1.getParent());
currentLargest = temp1;
temp1 = temp1.getParent();
temp2 = temp2.getParent();
} else if(temp1.getParent() != null){
temp1 = temp1.getParent();
} else if(temp2.getParent() != null){
temp2 = temp2.getParent();
}
if(temp1.getParent() == null && temp2.getParent() == null){
found = true;
}
}
if(nodeDepth(temp1) >= largestDepth){
return temp1;
} else{
return currentLargest;
}
}
}
I edited it to make a list of ancestors of each node, but I'm not sure how to go around checking each one to see if the elements in the list's match up since they are usually different sizes.
Heres the new code:
ArrayList<PhyloTreeNode> list1 = new ArrayList<PhyloTreeNode>();
ArrayList<PhyloTreeNode> list2 = new ArrayList<PhyloTreeNode>();
if(node1 == null || node2 == null){
return null;
} else{
if(node1.getParent() != null){
list1.add(node1.getParent());
findLeastCommonAncestor(node1.getParent(), node2);
}
if(node2.getParent() != null){
list2.add(node2.getParent());
findLeastCommonAncestor(node1, node2.getParent());
}
}

We can use recursive post order traversal for computing lowest common ancestor,
Here is my Java implementation
Here a & b are given input data for which i have to find lowest common ancestors.
public static int lowestcommanancestors(Node root,int a,int b){
if(root==null)
return 0;
int x=lowestcommanancestors(root.left,a,b);
int y=lowestcommanancestors(root.right,a,b);
if(x+y==2){
System.out.println(root.getData());
return 0;
}
if(root.getData()==a || root.getData()==b){
return x+y+1;
}
else{
return x+y;
}
}
First i am checking whether given input node presenting in left subtree or not,if yes just return 1 else 0,Similarly for right sub tree.When sum becomes 2 first time that node will be lowest common ancestors.
Tell me if i am wrong or you are getting difficulties to understanding the code

Related

Unsure why this particular test case does not work for merging binary trees

CS Student here practicing on leetcode.
I've been given the following problem:
No idea if this code is any good or not, would appreciate some feedback there as well, but here is what I worked out:
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
TreeNode ret = traverse(root1, root2);
return ret;
}
public TreeNode traverse(TreeNode node1, TreeNode node2){
TreeNode newNode = new TreeNode();
if(node1 == null && node2 == null){
return null;
}
else if(node1 == null){
newNode.val = node2.val;
}
else if(node2 == null){
newNode.val = node1.val;
}
else{
newNode.val = node1.val + node2.val;
newNode.left = traverse(node1.left, node2.left);
newNode.right = traverse(node1.right, node2.right);
}
return newNode;
}
}
Seems to work ok with the sample input given in the example. When I submit the problem, however, I am given this case:
I arrive at the expected answer when I worked it out on paper based on the code I wrote. I am not sure why in this case my code is producing an erroneous result. Help me out here
EDIT: Changed phrasing for clarity
The issue is that you are returning value only when both the nodes are null and not for other case where either node is null. Your code is not going to else statement for "either null" case and it gets returned to the calling function.
Changed code below:
if(node1 == null && node2 == null){
return null;
}
else if(node1 == null){
newNode.val = node2.val;
return node2;
}
else if(node2 == null){
newNode.val = node1.val;
return node1;
}
else{
newNode.val = node1.val + node2.val;
newNode.left = traverse(node1.left, node2.left);
newNode.right = traverse(node1.right, node2.right);
}
Because newNode does not play a role, you can discard and merge directly into roo1 node.
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1 == null && root2 == null) {
return null;
} else if(root1 == null) {
return root2;
} else if (root2 == null) {
return root1;
} else {
root1.val = root1.val + root2.val;
root1.left = mergeTrees(root1.left, root2.left);
root1.right = mergeTrees(root1.right, root2.right);
}
return root1;
This should work for you.

How do I implement a priority queue with explicit links (using a triply linked datastructure)?

I am trying to implement a priority queue, using a triply linked data structure. I want to understand how to implement sink and swim operations, because when you use an array, you can just compute the index of that array and that's it. Which doesn't make sense when you use a triply-linked DS.
Also I want to understand how to correctly insert something in the right place, because when you use an array, you can just insert in the end and do a swim operation, which puts everything in the right place, how exactly do I compute that "end" in a linked DS?
Another problem would be removing the element with the biggest priority. To do that, for an array implementation, we just swap the last element with the first (the root) one and then, after removing the last element, we sink down the first one.
(This is a task from Sedgewick).
I posted this in case someone gets stuck doing this exercise from Sedgewick, because he doesn’t provide a solution for it.
I have written an implementation for maximum oriented priority queue, which can be modified according for any priority.
What I do is assign a size to each subtree of the binary tree, which can be defined recursively as size(x.left) + size(x.right) + 1. I do this do be able to find the last node inserted, to be able to insert and delete maximum in the right order.
How sink() works:
Same as in the implementation with an array. We just compare x.left with x.right and see which one is bigger and swap the data in x and max(x.left, x.right), moving down until we bump into a node, whose data is <= x.data or a node that doesn’t have any children.
How swim() works:
Here I just go up by doing x = x.parent, and swapping the data in x and x.parent, until x.parent == null, or x.data <= x.parent.
How max() works:
It just returns root.data.
How delMax() works:
I keep the last inserted node in a separate field, called lastInserted. So, I first swap root.data with lastInserted.data. Then I remove lastInserted by unhooking a reference to it, from its parent. Then I reset the lastInserted field to a node that was inserted before. Also we must not forget to decrease the size of every node on the path from root to the deleted node by 1. Then I sink the root data down.
How insert() works:
I make a new root, if the priority queue is empty. If it’s not empty, I check the sizes of x.left and x.right, if x.left is bigger in size than x.right, I recursively call insert for x.right, else I recursively call insert for x.left. When a null node is reached I return new Node(data, 1). After all the recursive calls are done, I increase the size of all the nodes on the path from root to the newly inserted node.
Here are the pictures for insert():
And here's my java code:
public class LinkedPQ<Key extends Comparable<Key>>{
private class Node{
int N;
Key data;
Node parent, left, right;
public Node(Key data, int N){
this.data = data; this.N = N;
}
}
// fields
private Node root;
private Node lastInserted;
//helper methods
private int size(Node x){
if(x == null) return 0;
return x.N;
}
private void swim(Node x){
if(x == null) return;
if(x.parent == null) return; // we're at root
int cmp = x.data.compareTo(x.parent.data);
if(cmp > 0){
swapNodeData(x, x.parent);
swim(x.parent);
}
}
private void sink(Node x){
if(x == null) return;
Node swapNode;
if(x.left == null && x.right == null){
return;
}
else if(x.left == null){
swapNode = x.right;
int cmp = x.data.compareTo(swapNode.data);
if(cmp < 0)
swapNodeData(swapNode, x);
} else if(x.right == null){
swapNode = x.left;
int cmp = x.data.compareTo(swapNode.data);
if(cmp < 0)
swapNodeData(swapNode, x);
} else{
int cmp = x.left.data.compareTo(x.right.data);
if(cmp >= 0){
swapNode = x.left;
} else{
swapNode = x.right;
}
int cmpParChild = x.data.compareTo(swapNode.data);
if(cmpParChild < 0) {
swapNodeData(swapNode, x);
sink(swapNode);
}
}
}
private void swapNodeData(Node x, Node y){
Key temp = x.data;
x.data = y.data;
y.data = temp;
}
private Node insert(Node x, Key data){
if(x == null){
lastInserted = new Node(data, 1);
return lastInserted;
}
// compare left and right sizes see where to go
int leftSize = size(x.left);
int rightSize = size(x.right);
if(leftSize <= rightSize){
// go to left
Node inserted = insert(x.left, data);
x.left = inserted;
inserted.parent = x;
} else{
// go to right
Node inserted = insert(x.right, data);
x.right = inserted;
inserted.parent = x;
}
x.N = size(x.left) + size(x.right) + 1;
return x;
}
private Node resetLastInserted(Node x){
if(x == null) return null;
if(x.left == null && x.right == null) return x;
if(size(x.right) < size(x.left))return resetLastInserted(x.left);
else return resetLastInserted(x.right);
}
// public methods
public void insert(Key data){
root = insert(root, data);
swim(lastInserted);
}
public Key max(){
if(root == null) return null;
return root.data;
}
public Key delMax(){
if(size() == 1){
Key ret = root.data;
root = null;
return ret;
}
swapNodeData(root, lastInserted);
Node lastInsParent = lastInserted.parent;
Key lastInsData = lastInserted.data;
if(lastInserted == lastInsParent.left){
lastInsParent.left = null;
} else{
lastInsParent.right = null;
}
Node traverser = lastInserted;
while(traverser != null){
traverser.N--;
traverser = traverser.parent;
}
lastInserted = resetLastInserted(root);
sink(root);
return lastInsData;
}
public int size(){
return size(root);
}
public boolean isEmpty(){
return size() == 0;
}
}

java Delete a Binary Tree node containing two children

This is the last case where the node to be deleted has two children. I cant figure out what I am doing wrong . Please help.
//BTNode has two children
else if (u.getLeft() != null && u.getRight() != null){
//if node to delete is root
BTNode<MyEntry<K,V>> pred = u.getRight();
while (pred.getLeft().element() != null){
pred = pred.getLeft();
}
BTNode<MyEntry<K,V>> predParent = pred.getParent();
if (!hasRightChild(pred)){
predParent.setLeft(new BTNode<MyEntry<K,V>>(null,predParent,null,null));}
if (hasRightChild(pred)){
BTNode<MyEntry<K,V>> predChild = pred.getRight();
predParent.setLeft(predChild);
predChild.setParent(predParent);
}
return returnValue;
ok so modify it like this ??
u.setElement(succ.element());
BTNode<MyEntry<K,V>> succParent = succ.getParent();
if (!hasLeftChild(succ)){
succParent.setRight(new BTNode<MyEntry<K,V>>(null,succParent,null,null));}
if (hasLeftChild(succ)){
BTNode<MyEntry<K,V>> predChild = succ.getLeft();
succParent.setRight(predChild);
predChild.setParent(succParent);
}
return returnValue;
From wikipedia:
Deleting a node with two children: Call the node to be deleted N. Do
not delete N. Instead, choose either its in-order successor node or
its in-order predecessor node, R. Replace the value of N with the
value of R, then delete R.
So, take for example the left children, and then find the rightmost leaf in that subtree, then replace the information of the node to delete with that of the leaf, and then delete that leaf easily.
You might want to create a function that returns the rightmost leaf from a subtree.
I have given the code for deletion of a node in a BST which would work for any condition and that too using a for loop.
public void delete(int key) {
Node<E> temp = find(key);
System.out.println(temp.key);
for (;;) {
// case 1 : external node
if (temp.isExternal()) {
if (temp.getParent().getrChild() == temp) {
temp.parent.rightchild = null;
temp = null;
} else {
temp = null;
}
break;
}
// case2 : one child is null
else if ((temp.getlChild() == null) || (temp.getrChild() == null)) {
if ((temp.parent.leftchild != null) && temp.getParent().getlChild().key == temp.key) {
if (temp.getlChild() == null) {
temp.getParent().setLeft(temp.getrChild());
temp.getrChild().setParent(temp.getParent());
break;
}
else
temp.getParent().setLeft(temp.getlChild());
temp.getlChild().setParent(temp.getParent());
}
else {
if (temp.rightchild != null) {
System.out.println("in");
temp.getParent().setRight(temp.getrChild());
temp.getrChild().setParent(temp.getParent());
break;
}
else
temp.getParent().setRight(temp.getlChild());
temp.getlChild().setParent(temp.getParent());
}
break;
}
// case 3 : has both the children
else {
int t = temp.key;
temp.key = temp.getlChild().key;
temp.getlChild().key = t;
temp = temp.getlChild();
continue;
}
}
}

a method to count the number of nodes with 2 children in Binary search tree

Thats the best I could come up but it still doesn't work cause it returns 1 even if there was more than one node that have two children.
int countTwoChildren(Node node)
{
if(node==null) {
return 0;
}
if(node.left!=null && node.right!=null) {
return 1;
}
return countTwoChildren(node.left) + countTwoChildren(node.right);
}
Can anyone find any error in above piece of code?
One small thing missing:
int countTwoChildren(Node node)
{
if(node==null) {
return 0;
}
if(node.left!=null && node.right!=null) {
return 1 + countTwoChildren(node.left) + countTwoChildren(node.right);
}
return countTwoChildren(node.left) + countTwoChildren(node.right);
}
Your problem is that if a node has two children, you don't descend down its own children. You should change the order of checks:
int countTwoChildren(Node node)
{
int nc;
if(node==null) {
return 0;
}
nc = countTwoChildren(node.left) + countTwoChildren(node.right);
if(node.left!=null && node.right!=null) {
return nc++;
}
return nc;
}
Of course, this whole thing can be written in one line:
int countTwoChildren(Node node)
{
return (node == null
? 0
: countTwoChildren(node.left) + countTwoChildren(node.right) +
(node.left!=null && node.right!=null ? 1 : 0));
}
int countTwoChildren(Node node)
{
if (node == null)
return 0;
int here = node.left != null && node.right != null ? 1 : 0;
int left = countTwoChildren(node.left);
int right = countTwoChildren(node.right);
return here + left + right;
}
Well all your missing is an else, like you have an if statement that checks if the node has both left & right links not null, but what if it's null,
You can simply add the else:
if(node.left!=null && node.right!=null) {
return 1 + countTwoChildren(node.left) + countTwoChildren(node.right);
}else{
return countTwoChildren(node.left) + countTwoChildren(node.right);
}
Also you went wrong when you said if both left and right nodes are not null it will just return 1, you should continue traversing the tree to find the other by recursively calling the countTwoChildren for the left nodes and the right nodes respectively.
Your program will terminate the very first time if root has both left and right node so it will return back 1 , and will not go in recursive call . Here is the solution , hope it helps
public static int numberOfFullNode(TreeDemo root){
if(root==null)
return 0;
else if(root.left!=null && root.right!=null)
return 1+numberOfFullNode(root.left)+numberOfFullNode(root.right);
else return 0;
}
The question is already answered well,Just sharing the iterative solution for the same problem :
public static int findTheNumberOfFullNodesIterative(BTNode root) {
int noOfFullNodes = 0;
if (root == null) {
return 0;
}
Queue<BTNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
BTNode temp = q.poll();
if (temp.getLeft() != null && temp.getRight() != null) {
noOfFullNodes++;
}
if (temp.getLeft() != null) {
q.offer(temp.getLeft());
}
if (temp.getRight() != null) {
q.offer(temp.getRight());
}
}
return noOfFullNodes;
}

NullPointerException with while loop using compareTo

For our homework, I have to take in Chair objects and add them to the DoublyLinkedList that we made; it has to be sorted by alphabetical order, if style is the same alphabetically, we sort by color
When I try to go through the loop, I keep getting a NullPointerException.
public void add(Chair element){
if(isEmpty() || first.object.style.compareTo(element.style) > 0 || (first.object.style.compareTo(element.style) == 0 && first.object.color.compareTo(element.color) >= 0){
addFirst(element);
}else if(first.object.style.compareTo(element.style) <= 0){
Node temp = first;
Node insert = new Node(); insert.object = element;
while(temp.object.style.compareTo(element.style) <= 0) //This is where the nullPointerException occurs
if(temp.hasNext())
temp = temp.next;
while(temp.object.style.compareTo(element.style) == 0 && temp.object.color.compareTo(element.color) <= 0)
if(temp.hasNext())
temp = temp.next;
insert.prev = temp.prev;
insert.next = temp;
temp.prev.next = insert;
temp.prev = insert;
}
}
This is the code where I put the information into the DoublyLinkedList
try{
FileReader fr = new FileReader(filename);
Scanner sc = new Scanner(fr);
String[] temp;
while(sc.hasNext()){
temp = sc.nextLine().split(" ");
if(temp[0].equals("Bed")){}
else if(temp[0].equals("Table")){
// tables.add(new Table(Integer.parseInt(temp[1]), Integer.parseInt(temp[2]), Integer.parseInt(temp[3]), temp[4]));
}else if(temp[0].equals("Desk")){}
else if(temp[0].equals("Chair")){
chairs.add(new Chair(temp[1], temp[2]));
}else if(temp[0].equals("Bookshelves")){}
else{
color = temp[0];
}
}
while(!chairs.isEmpty())
System.out.println(chairs.removeFirst().info());
System.out.println();
//while(!tables.isEmpty())
// System.out.println(tables.removeFirst().info());
}catch(Exception e){e.printStackTrace();}
This is the DoublyLinkedList class that I've made:
class CDoublyLinkedList{
Node first, last;
public CDoublyLinkedList(){
first = new Node(); last = new Node();
first.prev = last.next = null;
first.object = last.object = null;
first.next = last;
last.prev = first;
}
public boolean isEmpty(){
return first.object == null;
}
public void addFirst(Chair element){
Node insert = new Node();
insert.object = element;
insert.prev = null;
insert.next = first;
first.prev = insert;
first = insert;
}
public void add(Chair element){
if(isEmpty() || first.object.style.compareTo(element.style) > 0 || (first.object.style.compareTo(element.style) == 0 && first.object.color.compareTo(element.color) >= 0){
addFirst(element);
}else if(first.object.style.compareTo(element.style) <= 0){
Node temp = first;
Node insert = new Node(); insert.object = element;
while(first.object.style.compareTo(element.style) <= 0)
if(temp.hasNext())
temp = temp.next;
while(first.object.style.compareTo(element.style) == 0 && first.object.color.compareTo(element.color) <= 0)
if(temp.hasNext())
temp = temp.next;
insert.prev = temp.prev;
insert.next = temp;
temp.prev.next = insert;
temp.prev = insert;
}
}
public Chair removeFirst(){
Chair tobedeleted = first.object;
Node temp = first.next;
first = temp;
first.prev = null;
return tobedeleted;
}
private class Node{
Node next, prev;
Chair object;
public boolean hasNext(){
return next != null;
}
}
}
The Chair class:
class Chair extends Furniture{
public String style, color;
public Chair(String s, String c){
style = s; color = c;
}
public String toString(){
return color;
}
public String getType(){
return "Chair";
}
public String info(){
return (color+", "+style);
}
}
Can someone please explain to me why I keep getting this error? Thank you!
EDIT:
while(temp.object.style.compareTo(element.style) <= 0) //This is where the nullPointerException occurs
chairs.add(new Chair(temp[1], temp[2]));
java.lang.NullPointerException
at CDoublyLinkedList.add(Furnish2SS.java:119)
at Furnish2SS.main(Furnish2SS.java:23)
java.lang.NullPointerException
at CDoublyLinkedList.add(Furnish2SS.java:119)
at Furnish2SS.main(Furnish2SS.java:23)
EDIT2: SOLVED!
I changed my while loop to:
while(temp.object != null && element != null && (temp.object.compareTo(element) == 0 || temp.object.compareTo(element) == -1))
The reason I got the error was because I wasn't checking for null every iteration.
You say this is the line of code causing the exception:
while(temp.object.style.compareTo(element.style) <= 0)
You probably should set a debugger breakpoint on that line and use a debugger to determine which of the values is null. But it's hard for me to explain here full instructions on how to setup and use a debugger (that doesn't mean you shouldn't learn! You should. There are lots of tutorials. Google it.) So instead of writing a tutorial on debuggers, I'll just post code that will tell you which variable is null:
if (temp == null) {
System.out.println("temp is null");
} else if (temp.object == null) {
System.out.println("temp.object is null");
} else if (temp.object.style == null) {
System.out.println("temp.object.style is null");
}
if (element == null) {
System.out.println("element is null");
} else if (element.style == null) {
System.out.println("element.style is null");
}
while(temp.object.style.compareTo(element.style) <= 0) //This is where the nullPointerException occurs
{
if(temp.hasNext())
temp = temp.next;
if (temp == null) {
System.out.println("loop: temp is null");
} else if (temp.object == null) {
System.out.println("loop: temp.object is null");
} else if (temp.object.style == null) {
System.out.println("loop: temp.object.style is null");
}
if (element == null) {
System.out.println("loop: element is null");
} else if (element.style == null) {
System.out.println("loop: element.style is null");
}
}
If you use the above code statements to replace these three lines of your code:
while(temp.object.style.compareTo(element.style) <= 0) //This is where the nullPointerException occurs
if(temp.hasNext())
temp = temp.next;
you will know which variable is null based on which statement is printed. Hopefully you can take it from there. (The usual way to fix a NullPointerException is to take the steps necessary to ensure the offending null variable actually has a valid, non-null value by the time the program reaches the line of the NullPointerException).
Take a look at addFirst(Chair element). That method is really screwed up. It creates a new Node which contains the correct Chair. It then sets its prev to null. Then it sets next to first. And this is what's causing all of your troubles. Because first points to an empty Node. You end up with this:
first points to your new Node. That one points to a Node which holds no Chair. That one again points to last.
e:
Your whole code looks like you had at least two different approaches on implementing your list and threw them toghether. There are some more errors but since this is homework I guess it's not that bad if you try fixing it first.
If you can't figure out how to correct that, ask here.
PS: Sorry for all of the editing and (un)deleting my answeres (if you noticed). I'm a bit tired and kept causing new errors by fixing old ones until I finally figured out what was the true cause of all this.

Categories