Identify loop or recursion in the list - java

I want to identify the loop or recursion in the list for the below structure of the node. How can I identify the same?
public class EntityNode {
private EntityNode nextNode; // Points to the next node
}
Example,
Node1 -> Node2 -> Node3 -> Node4 -> Node5 -> Node6 -> Node4
Here, you can see that Node6 is pointing to Node4, and here there comes the looping or recursion and my code will go into infinite. So what if I want to find out this type of scenario with the optimum performance level?

This is actually an interview question I have heard a few times. While I have never tried to implement any sort of loop detection, the answer that most of the interviewers seemed to like is iterating through the list and storing the visited nodes in a hashtable. If you get a collision while storing into the table, then you have a loop in your list.
Edit: In an attempt to offer some code for the example, here is what I would probably try to do (assuming you have some sort of LinkedList<EntityNode> object). I updated this to use a HashSet instead of a HashMap so it was more straightforward (as pointed out by PM 77-1).
public bool detectLoop(LinkedList<EntityNode> list)
{
Set<EntityNode> nodeSet = new HashSet<EntityNode>();
EntityNode curNode = list.getHead();
boolean loopDetected = false;
if(curNode != null)
{
while(curNode.getNextNode() != null && !loopDetected)
{
cureNode = curNode.getNextNode();
loopDetected = !nodeSet.add(curNode);
}
}
return loopDetected;
}
I haven't had the opportunity to test this, but this should work. The reason being that the add() method for a HashSet returns true if this set did not already contain the specified element. So if there is a EntityNode already exists in the set, it will return false, meaning that there was a loop detected.
Since my answer has sort of taken off, I want to say that there are other solutions to this as well. The other one that has been pointed out in this thread is the tortoise and the hare algorithm. You can find more information on that in this thread or at this wiki page.

You should have two EntityNode objects. Both start at Node1. Have the first object move two nodes down, and the second only move one node down. Repeat this until you either reach the end (there was no cycle) or the two objects meet at the same node (there is a cycle).
For your example:
n1: Node1, n2: Node1
n1: Node3, n2: Node2
n1: Node5, n2: Node3
n1: Node4, n2: Node4 -> cycle!!
For pseudocode:
while (n1.nextNode isn't null):
n1 = n1.nextNode.nextNode
n2 = n2.nextnode
if (n1 equals n2): return 'there is a loop!'

I searched on the net and found that this type of problem is called the tortoise and hare algorithm. The Wikipedia page is also here for the same.
As codaddict states in their answer here:
The idea is to have two references to the list and move them at
different speeds. Move one forward by 1 node and the other by 2 nodes.
If the linked list has a loop they will definitely meet.
Else either of the two references(or their next) will become null.
Java code implementing the algorithm:
boolean hasLoop(EntityNode first) {
if (first == null) // list does not exist..so no loop either.
return false;
EntityNode slow, fast; // create two references.
slow = fast = first; // make both refer to the start of the list.
while (true) {
slow = slow.nextNode; // 1 hop.
if (fast.nextNode != null)
fast = fast.nextNode; // 2 hops.
else
return false; // next node null => no loop.
if (slow == null || fast == null) // if either hits null..no loop.
return false;
if (slow == fast) // if the two ever meet...we must have a loop.
return true;
}
}

I think you can make a "visited" flag. Or you can use unintersecting sets, which helps to identify loops in O(N *log N).
P.S. I must admit that this method is more appropriate if you need to build a graph without cycles.

I like Bhavik's answer if you are constrained by memory limits. It doesn't create any possibly large objects to determine the answer.
If there is a loop then the single step and double step methods of walking through the EntityNodes will have to intersect.
Here is sample code to test with -
public class EntityNode {
private EntityNode nextNode = null; // Points to the next node
public static void main(String[] args) {
final EntityNode head = new EntityNode();
// Create small sample (test with even and odd number)
EntityNode tail = head;
for (int i = 0; i < 6; i++) {
EntityNode newNode = new EntityNode();
tail.nextNode = newNode;
tail = newNode;
}
// Add "loop" node
tail.nextNode = head;
System.out.println(detectLoop(head));
}
// Return true if a loop is found
private static boolean detectLoop(EntityNode head) {
boolean loopDetected = false;
if (head != null) {
EntityNode singleStep = head;
EntityNode doubleStep = head;
// If either EntityNode is null and end has been found
while ((singleStep.nextNode != null)
&& (doubleStep.nextNode != null)) {
singleStep = singleStep.nextNode;
// Assert doubleStepper.nextNode != null
doubleStep = doubleStep.nextNode.nextNode;
// If there is a "Collision" then there is a loop
loopDetected = (doubleStep == singleStep);
if (loopDetected) {
break;
}
}
}
return loopDetected;
}

Just traverse the list while keeping every visited node in a hash set. If the node you are adding is ever already present in the set, you have a cycle.

A.-Keep count of the amount of added nodes. Then start a loop through them, while counting the loops. If loopsAmount>nodesAmount, you have recursion.
B.-Keep track of the visited nodes. If a node is visited twice, you have recursion.
C.-Index the nodes while creating them. If node.nextNode.Index-1 != node.Index, you have recursion.

Related

How is the top Node of my Binary Search Tree updated when only making references to its copies

This question also applies to various linked lists methods as well. So, when I have a method:
public void insert(String key)
{
if(top == null)
{
top = new Node(key);
}else {
Node newNode = new Node(key);
Node rover = top;
Node prev = top;
boolean wentLeft = true;
while(rover != null)
{
if (rover.getName().compareTo(key) < 0)
{
prev = rover;
rover = rover.getRight();
wentLeft = false;
}else {
wentLeft = true;
prev = rover;
rover = rover.getLeft();
}
}
if(wentLeft == true)
{
prev.setLeft(newNode);
}else {
prev.setRight(newNode);
}
}
nElems++;
}
How is the top of the Binary Search Tree and its children updated despite not being directly set anywhere in the method?
I know this likely has something to do with shallow copying and that like rover/prev are still referencing top in memory but I still don't really get it.
Even though I feel like I understand Linked Lists and Binary Search Trees on a conceptual level I don't feel comfortable moving forward with them without understanding this.
There are no copies being made. When you assign prev = top, that only creates another reference to the same object as top, not a copy.
The code works because nodes are inserted one by one.
When prev.setLeft/setRight is called, prev is already in the tree because it was inserted before. So prev is already in the tree, i. e. the parent of prev is top, or the parent of the parent of prev, you get the idea. Thus, when new_node becomes child of prev, it becomes part of the tree.
This is what makes linked lists and trees so useful. When you insert an element, you only have to make one connection.

Remov n-th node from the end of list [LeetCode]

The question is very straight forward and I got the algorithm as well. The only thing I don't understand is the return statement. why do we need to return dummy.next, when we haven’t make any change to dummy at all.
I guess my question is when we initially set slow and fast equal to dummy, aren't we just making a deep copy of the list/dummy (meaning whatever change we made in either of them does not affect dummy), or am i missing something..?
Any help would be appreciated. if you can back up your explanation with an example, would be awesome.
And here is link to the question: https://leetcode.com/problems/remove-nth-node-from-end-of-list/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode slow = dummy, fast = dummy;
for(int i = 0; i <= n ; i++){
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}
The only difference that I can see between using the dummy and not would be in the case of having to remove the first element in the list. In that case, without using the dummy there would not be a way to remove the head node. However, this can easily be fixed by adding a simple check during the initial loop.
Here is my solution, omitting the use of the dummy head.
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode slow = head, fast = head;
for(int i = 0; i <= n ; i++){
if (fast == null) {
return head.next;
}
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
}
To answer your other questions,
aren't we just making a deep of the list/dummy
there is no deep copying going on since the dummy keeps a reference of the head, not a copy.
why do we need return dummy.next, when we haven’t make any change to dummy at all.
the dummy is defined to be before the head. so when we want to return the changed head, we return the next node after dummy. If we just returned dummy, then the answer that we would get would have an extra 0 in the front of it, which we don't want.
To answer your questions,
when we initially set slow and fast equal to dummy, aren't we just
making a deep of the list/dummy
No it doesn't. The assignment is by reference as ListNode is a reference type. Thus changing any of dummy, slow, fast will show its affect on all three variables.
the only thing I don't understand is the return statement. why do we
need return dummy.next
As for the return statement, we still need to return the start of list that was provided to us as a parameter head in function, which is being pointed by dummy.next
As for why is the operations directly not performed on head and there is need of dummy variable and steps
ListNode dummy = new ListNode(0);
dummy.next = head;
the reason might be cover up all edge scenarios. eg : Linked List contains only one node and it is removed or the first node of linked list is removed.

Implement an algorithm to delete a node in the middle of a single linked list, given only access to that node

Example input: the node ‘c’ from the linked list a->b->c->d->e Result: nothing is returned, but the new linked list looks like a->b->d->e
I do understand that ppl have already asked this question before, but since my reputation is not high enough yet, I couldn't ask my question in that thread. so here goes my quesetion:
So in the solution, when deleting the middle node we do:
public static boolean deleteNode(LinkedListNode n) {
if (n == null || n.next == null) {
return false; // Failure
}
LinkedListNode next = n.next;
n.data = next.data;
n.next = next.next;
return true;
}
But what I don't understand is that why can't I just do n = next?
It is probably a trivial question, but I didn't seem to find a good explanation for this question
If you just do n = next then you have only changed what object your local reference variable n refers to; you haven't modified any part of the list.
The trick to "deleting" the current node is to overwrite it with the next one:
n.data = next.data;
n.next = next.next;
Now you are modifying fields of the object that is referred to by n, which is a part of the actual list.
In C++, the code you wrote would look like this:
bool deleteNode(LinkedListNode* n) {
if (n == null || (*n).next == null) {
return false; // Failure
}
LinkedListNode* next = (*n).next;
(*n).data = (*next).data;
(*n).next = (*next).next;
return true;
}
So what does that mean? When you call this method, in C++ it would look like this:
LinkedListNode* listNode = new LinkedListNode();
deleteNode(&listNode);
This is important, because that means you're just sending an address over, and not the entire object. This means that you don't actually have access to the node you gave as a parameter to the method, you only have a reference to its address.
Basically, in Java, you can't do the following C++ code:
*n = *next;
You can't modify the listNode object that's outside of the method. You only get its address. And you are only modifying the copy of its address, not the address itself.
Basically, it's because in Java, the pointer of the class is passed by value (as a copy), and primitives are also passed by value (as a copy).
somehow, it overwrites the current node which is supposed to be deleted with the
data of next node to it,and delete the next node.
LinkedListNode next = n.next;
n.data = next.data;
n.next = next.next;
That is how the code comes.

Threaded Binary Search Tree Java

I have managed to create a threaded binary search tree through it's insertion method. I now need to traverse the tree and print in order. I have code that works, but I used an boolean flag to determine whether or not I have printed that specific node. For this assignment it must not be recursive. I was wondering if there is a possible way to completely clear all of the boolean flags to false, because if I try to print again it will, and does, not work. Any suggestions? here is the copy of my display method.
public void display(){
Node parent=top;
Node current=top;
while (current != null){
parent = current;
current = current.getLeft();
}
System.out.println(parent);
current=parent.getRight();
while(current!= null){
while(current.isHasLeftThread()==false && current.getLeft().hasBeenHere()==false){
parent = current;
current=current.getLeft();
}
System.out.println(current);
current.setBeenHere(true);
current=current.getRight();
System.out.println(current);
current.setBeenHere(true);
current = current.getRight();
}
}
You can use a fresh Collections.newSetFromMap( new IdentityHashMap< Node, Boolean >() ) to do the bookkeeping for visited nodes every time rather than including a flag in the Node class itself.
Incidentally, comparing Boolean expressions to the constant values true or false is just awful style. For example
while( e == false )
is much more effectively expressed as
while( !e )

ConcurrentLinkedQueue Code Explanation

http://www.java2s.com/Open-Source/Java-Open-Source-Library/7-JDK/java/java/util/concurrent/ConcurrentLinkedQueue.java.htm
The above is the source code of ConcurrentLinkedQueue.
I am not able to understand one condition.
How the condition (p == q) will come in the below snippet code from offer method
public boolean offer(E e) {
checkNotNull(e);
final Node<E> newNode = new Node<E>(e);
for (Node<E> t = tail, p = t;;) {
Node<E> q = p.next;
if (q == null) {
// p is last node
if (p.casNext(null, newNode)) {
// Successful CAS is the linearization point
// for e to become an element of this queue,
// and for newNode to become "live".
if (p != t) // hop two nodes at a time
casTail(t, newNode); // Failure is OK.
return true;
}
// Lost CAS race to another thread; re-read next
}
else if (p == q)
// We have fallen off list. If tail is unchanged, it
// will also be off-list, in which case we need to
// jump to head, from which all live nodes are always
// reachable. Else the new tail is a better bet.
p = (t != (t = tail)) ? t : head;
else
// Check for tail updates after two hops.
p = (p != t && t != (t = tail)) ? t : q;
}
}
and also what does the author mean by "We have fallen off List"
The ConcurrentLinkedQueue allows concurrent modification of the internal list while traversing it. This implies that the node you are looking at could have been removed concurrently. To detect such situations the next pointer of a removed node is changed to point to itself. Look at updateHead (L302) for details.
The condition asks the question "Is the current node the same as the next node?"
If so, you've fallen off list ( documentation in line. )
The basic outline of steps is:
create a new node for the offered data.
walk the list to find the last node
insert new node as new tail.
The other parts of the if statement are handling concurrent modification issues.
To better understand what's going on, read Node.casTail() and the casNext()

Categories

Resources