Check if two linked list are equal in java - java

I am basically completing a hacker rank excercise where you return 1 if the list is completely equal meaning there are same number of nodes in two lists and all the values in nodes also equal. Otherwise you return 0.
This is the method I wrote and for some reason I keep failing the test case i am not sure why. I wrote down some test cases in my book and did hand tracing and still can't seem to figure it out why.
int CompareLists(Node headA, Node headB) {
// This is a "method-only" submission.
// You only need to complete this method
Node temp = headA;
Node temp2 = headB;
int equal = 1;
if(temp == null && temp2 == null){
equal = 1;
}
else if((temp == null && temp2 != null) || (temp!=null && temp2 == null)){
equal = 0;
}
else{
while(temp.next != null){
if(temp.data != temp2.data || temp2.next == null){
equal = 0;
break;
}
temp = temp.next;
temp2 = temp2.next;
}
if(temp2.next != null){
equal = 0;
}
}
return equal;
}
Yes i found many solutions online but I am more curious as to why my solution is not working.

The code
while(temp.next != null){
if(temp.data != temp2.data || temp2.next == null){
equal = 0;
break;
}
temp = temp.next;
temp2 = temp2.next;
}
if(temp2.next != null){
equal = 0;
}
will never compare the last element of the first list with the corresponding element of the second list because your loop stops early. Try this instead:
while(temp != null){
if(temp2 == null || temp.data != temp2.data){
equal = 0;
break;
}
temp = temp.next;
temp2 = temp2.next;
}
if(temp2 != null){
equal = 0;
}
Using temp != null as loop condition makes sure, we also check the last element. The same adaption has been done for the check temp2.next == null, which is now temp2 == null. And this check has to be done before the comparison of data, in order to avoid a NullPointerException during the data comparison.
I personally would write that part more like this:
while(temp != null && temp2 != null){
if(temp.data.equals(temp2.data)){
return false;
}
temp = temp.next;
temp2 = temp2.next;
}
return temp == temp2;
I consider it easier to understand because it is symmetric. Usage of equals makes sure, we compare the actual content of the payload, not just references. I'd also use boolean as return type.

You can use recursive function.
public boolean isIdenticalRecursive(Node a, Node b) {
if (a == null && b == null) {
return true;
}
if (a.data != b.data)
return false;
return isIdenticalRecursive(a.next, b.next);
}
Hope this will help !! :)

This works:
int CompareLists(Node headA, Node headB) {
if ((headA == null)^(headB == null))
return false;
if ((headA == null) && (headB == null))
return true;
if (headA.data != headB.data)
return false;
return CompareLists(headA.next, headB.next);
}

And the cleanest way ever:
static boolean compareLists(SinglyLinkedListNode head1, SinglyLinkedListNode head2) {
while(head1 != null && head2 != null && head1.data == head2.data) {
head1 = head1.next;
head2 = head2.next;
}
return head1 == head2;
}

public int compare_list(Node A, Node B) {
Node tail_A = A;
Node tail_B = B;
while(tail_A != null && tail_B != null){
if(tail_A.val != tail_B.val){
return 0;
}
tail_A = tail_A.next;
tail_B = tail_B.next;
}
if(tail_A == tail_B){
return 1; // if Equal lengths and same values
}
else{
return 0; // Only length are not equal
}
}

Related

How to implement skiplist in java (adding values, checking for values)?

I want to write a method that allows me to insert a value to the list (generic implementation). Furthermore i want to check wether a value in already in the list or not. I just want to know wether this is how its supposed to be or not.
In order to check wether a value is already contained within the list:
public boolean contains(T value) {
boolean searchedValue;
if (head == null || baseListLength == 0) {
searchedValue= false;
} else {
IndexListEntry<T> blub= head;
while ((blub.next != null) && (blub.next.value.compareTo(value) <= 0)) {
value= blub.next;
}
searchedValue= baseList.contains(value, blub.pointer);
}
return searchedValue;
}
and to add any value to the list:
public boolean addValue(T value) {
BaseListEntry<T> offs= baseList.add(value);
if (indexListLength < indexMaxLength) {
if (head == null) {
head = new IndexListEntry<T>(value, null, offs);
} else {
IndexListEntry<T> temp= head;
while ((temp.next != null) && (temp.next.value.compareTo(value) < 0)) {
temp= temp.next;
}
if (temp.next == null) {
temp.next = new IndexListEntry<T>(value, null, offs);
} else {
temp.next = new IndexListEntry<T>(value, temp.next, offs);
}
}
indexListLength++;
} else {
IndexListEntry<T> currentIndex = head.next;
int intervalWidth = baseListLength / indexMaxLength;
int intervalAdj = baseListLength % indexMaxLength;
int indexPosition = 0;
for (int i = 1; i < indexMaxLength; i++) {
int rip= 0;
if (intervalAdj - i >= 0)
rip= 1;
indexPosition = indexPosition + intervalWidth + rip;
BaseListEntry<T> newIndexTarget = baseList.getBaseListEntry(indexPosition);
currentIndex.pointer = newIndexTarget;
currentIndex.value = newIndexTarget.value;
currentIndex = currentIndex.next;
}
}
return true;
}
Are there any other methods to accomplish that goal? is my code somewhat correct. I am doubting everything I code right now and I kinda need confirmation from someone who knows more than me about this.
This is of course not everything i got. there are more classes to it but these are not the problem at hand so i dont thnk i need to upload that code as well.

Given two trees, return true if they are structurally identical they are made of nodes with the same values arranged in the same way

public static boolean identical(treenode<Integer> root1,treenode<Integer> root2)
{
boolean ans;
for(int i=0;i<root1.children.size();i++)
for(int j=0;j<root2.children.size();j++)
{
boolean subans=identical(root1.children.get(i),root2.children.get(j));
ans=subans;
}
if(root1.data==root2.data)
{
ans=true;
}/* what's wrong with the code*/
else{
ans=false;
}
return ans;
}/* how can i improve it ? */
i am not able to understand why my code is not working.please tell me the solutions to fix it.
Your for loop is going through every recursive call of identical before evaluating the boolean return of those recursive calls. In other words, you're not evaluating the data of all of the children through your recursive calls. I believe with your code that you may only be evaluating the last child node of every node in the tree (going down the right-most side).
You also have a nested for loop, which is unnecessary in your case.
What I propose is this:
1) Check that the values of your current nodes are the same. If not, or if at least one is null, return false immediately.
2) Check that the sizes of the children are the same for both nodes. If not, return false.
3) Call this recursively with each child node.
This is a depth first, left-side-first search.
private boolean structurallyIdentical(Node tnode, Node onode) {
if(tnode == null && onode == null) {
return true;
}
if(tnode != null && onode != null) {
// check that the left branch is identical
boolean left = structurallyIdentical(tnode.left, onode.left);
// check that the right branch is identical
boolean right = structurallyIdentical(tnode.right, onode.right);
// only identical, if both branches match
return (left && right);
}
return false;
}
A little improvement based on #Vansh Nandwani's answer.
SBT = Same Binary Tree
public boolean SBT(BinNode root1, BinNode root2)
{
if (root1 == null && root2 == null) return true;
if (root1 != null && root1 != null) {
if (root1.value() == root2.value())//check if the values are the same
{
boolean left = SBT(root1.left(), root2.left());
boolean right = SBT(root1.right(), root2.right);
return (left && right);}
}
return false;
}
public class Solution {
/* TreeNode structure
class TreeNode<T> {
T data;
ArrayList<TreeNode<T>> children;
TreeNode(T data){
this.data = data;
children = new ArrayList<TreeNode<T>>();
}
}*/
public static boolean checkIdentical(TreeNode<Integer> root1, TreeNode<Integer> root2){
if(root1.children.size()!=root2.children.size())
{
return false;
}
if(root1.children.size()==root2.children.size()){
if(root1.data==root2.data)
{
for(int i=0 ,j=0;i<root1.children.size()&&j<root2.children.size();i++ ,j++){
checkIdentical(root1.children.get(i),root2.children.get(j));
return true;
}
}
}
return false;
}
}
bool areIdentical(TreeNode<int> *root1, TreeNode<int> * root2)
{bool ans=false;
if(root1->children.size()!=root2->children.size())
{
ans =false;
}
if(root1->children.size()==root2->children.size()){
if(root1->data==root2->data)
{
for(int j=0;j<root1->children.size();j++){
areIdentical(root1->children[j],root2->children[j]);
ans=true;
}
}
}
return ans;
}
For general tree
Method 1:
bool areIdentical(TreeNode<int> *root1, TreeNode<int> * root2) {
if(root1 == NULL && root2 == NULL){
return true;
}
if((root1 == NULL && root2 != NULL) || (root1 != NULL && root2 == NULL)){
return false;
}
if((root1->data != root2->data)|| (root1->children.size() != root2->children.size())){
return false;
}
else if(root1->children.size() == root2->children.size()){
if(root1->data == root2->data){
for(int i=0,j=0;i<root1->children.size()&&j<root2->children.size();i++,j++){
areIdentical(root1->children[i],root2->children[j]);
return true;
}
}
}
return false;
}
//this solution may fail some testcase but
Method 2 : work perfectly fine
Method 2 :
bool areIdentical(TreeNode<int> *root1, TreeNode<int> * root2) {
if(root1 == NULL && root2 == NULL){
return true;
}
if((root1 == NULL && root2 != NULL) || (root1 != NULL && root2 == NULL)){
return false;
}
if((root1->data != root2->data)|| (root1->children.size() != root2->children.size())){
return false;
}
for(int i = 0;i < root1->children.size();++i){
TreeNode<int>* child1 = root1->children[i];
TreeNode<int>* child2 = root2->children[i];
if(!areIdentical(child1,child2)){
return false;
}
}
return true;
}
Structurally identical
public static boolean checkIdentical(TreeNode<Integer> root1, TreeNode<Integer> root2){
int size1=root1.children.size();
int size2=root2.children.size();
if(root1==null && root2==null){
return true;
}
if((root1==null && root2!=null) || (root1!=null && root2==null)){
return false;
}
if((root1.data!=root2.data)||(size1!=size2)){
return false;
}
if(size1==size2){
if(root1.data==root2.data){
for(int i =0;i<size1;i++){
for(int j=0;j<size2;j++){
TreeNode<Integer> child1=root1.children.get(i);
TreeNode<Integer> child2=root2.children.get(i);
if(!checkIdentical(child1,child2)){
return false;
}
}
}
}
}
return true;
}

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.

How to remove a node from a binary tree?

I need to write a method to delete a node from a binary tree. I tried reading and making use of other people's questions, kind of helped. Thing is I get some errors. I'm kind of confused.
Here is the code:
String delete(int k)
{
BSTNode maxfromleft = null;
BSTNode n = getNode(k);
BSTNode n1 = n;
if(n == null)
return null;
if (k < node.getKey())
n.left.setValue(delete(n.left.getKey()));
else if(k > node.getKey()){
n.right.setValue(delete(n.right.getKey()));
}
else{
if(n.right != null && n.left != null){
maxfromleft = max(n.left);
n.left.setValue(delete(n.left.getKey()));
n.setValue(maxfromleft.getValue());
}
else if(n.right == null){
n = n.left;
return n1.getValue();
}
else if(n.left == null){
n = n.right;
return n1.getValue();
}
}
return n.getValue();
}
private BSTNode max(BSTNode n) {
if (n == null)
return null;
if (n.right != null)
return max(n.right);
return n;
}
I get a NullPointerException error at this line:
n.left.setValue(delete(n.left.getKey()));
why?
How can I fix this?
All help is appreciated :)

How do I remove the leaves of a binary tree?

I'm trying to remove all of the leaves. I know that leaves have no children, this is what I have so far.
public void removeLeaves(BinaryTree n){
if (n.left == null && n.right == null){
n = null;
}
if (n.left != null)
removeLeaves(n.left);
if (n.right != null)
removeLeaves(n.right);
}
n = null; won't help you, since n is just a local variable of your function. Instead, you'd need to set n.left = null; or n.right = null; on the parent.
I won't give you a complete solution, since this smells a lot like homework, but you could, for example, add a return value to your function to indicate whether the node in question is a leaf or not and take appropriate actions in the parent (after the call to removeLeaves).
It's much easier if you break this down like this:
public void removeLeaves(BinaryTree n){
if (n.left != null) {
if (n.left.isLeaf()) {
n.removeLeftChild();
} else {
removeLeaves(n.left);
}
}
// repeat for right child
// ...
}
isLeaf, removeLeftChild and removeRightChild should be trivial to implement.
Instead of n = null, it should be:
if(n.parent != null)
{
if(n.parent.left == n)
{
n.parent.left = null;
}
else if(n.parent.right == n)
{
n.parent.right == null);
}
}
Since Java passes references by values n = null; simply does not work. With this line n was pointing to the leaf and now points to nothing. So you aren't actually removing it from the parent, you are just rerouting a dummy local reference. For the solution do what Matthew suggested.
Here's a simple java method to delete leaf nodes from binary tree
public BinaryTreeNode removeLeafNode(BinaryTreeNode root) {
if (root == null)
return null;
else {
if (root.getLeft() == null && root.getRight() == null) { //if both left and right child are null
root = null; //delete it (by assigning null)
} else {
root.setLeft(removeLeafNode(root.getLeft())); //set new left node
root.setRight(removeLeafNode(root.getRight())); //set new right node
}
return root;
}
}
Easy method with recusrion .
public static Node removeLeaves(Node root){
if (root == null) {
return null;
}
if (root.left == null && root.right == null) {
return null;
}
root.left = removeLeaves(root.left);
root.right = removeLeaves(root.right);
return root;
}
/* #author abhineet*/
public class DeleteLeafNodes {
static class Node{
int data;
Node leftNode;
Node rightNode;
Node(int value){
this.data = value;
this.leftNode = null;
this.rightNode = null;
}
}
public static void main(String[] args) {
Node root = new Node(1);
Node lNode = new Node(2);
lNode.leftNode = new Node(4);
root.leftNode = lNode;
Node rNode = new Node(3);
rNode.rightNode = new Node(5);
root.rightNode = rNode;
printTree(root);
deleteAllLeafNodes(root, null,0);
System.out.println("After deleting leaf nodes::");
printTree(root);
}
public static void deleteAllLeafNodes(Node root, Node parent, int direction){
if(root != null && root.leftNode == null && root.rightNode == null){
if(direction == 0){
parent.leftNode = null;
}else{
parent.rightNode = null;
}
}
if(root != null && (root.leftNode != null || root.rightNode != null)){
deleteAllLeafNodes(root.leftNode, root, 0);
deleteAllLeafNodes(root.rightNode, root, 1);
}
}
public static void printTree(Node root){
if(root != null){
System.out.println(root.data);
printTree(root.leftNode);
printTree(root.rightNode);
}
}
}
This should work-
public boolean removeLeaves(Node n){
boolean isLeaf = false;
if (n.left == null && n.right == null){
return true;
//n = null;
}
if (n!=null && n.left != null){
isLeaf = removeLeaves(n.left);
if(isLeaf) n.left=null; //remove left leaf
}
if (n!=null && n.right != null){
isLeaf = removeLeaves(n.right);
if(b) n.right=null; //remove right leaf
}
return false;
}

Categories

Resources