Home > Mobile >  Java LinkedList "Error - Found cycle in the ListNode," why does solution B work but not so
Java LinkedList "Error - Found cycle in the ListNode," why does solution B work but not so

Time:01-29

The following code results in an "Error - Found cycle in the ListNode" error

public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode current = head.next;
        while (current != null) {
            //move current to front of list
            ListNode temp = current.next;
            current.next = head;
            head = current;
            current = temp;
        }
        return head;
    }

Yet the following code works fine:

public ListNode reverseList(ListNode head) {
        ListNode curr = head;
        ListNode prev = null;
        while (curr != null) {
            //move current to front of list
            ListNode temp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = temp;
        }
        return prev;
    }

To me the code looks like it would do the same thing but instead of prev they use head. Ideas why it is different?

CodePudding user response:

The faulty code does not ever change the next member of the first node. Thus a cycle will be created between the first two nodes, which will become the last two nodes once the list has been reversed. It may help to visualise it with an example list having 1, 2 and 3 as node values:

The state when the loop is about to start its first iteration:

 head             current
  ↓                ↓
┌────────────┐   ┌────────────┐   ┌────────────┐
│ value:   1 │   │ value:   2 │   │ value:   3 │
│ next: ────────►│ next: ────────►│ next: null │
│            │   │            │   │            │
└────────────┘   └────────────┘   └────────────┘

Effect of ListNode temp = current.next;:

 head             current          temp
  ↓                ↓                ↓
┌────────────┐   ┌────────────┐   ┌────────────┐
│ value:   1 │   │ value:   2 │   │ value:   3 │
│ next: ────────►│ next: ────────►│ next: null │
│            │   │            │   │            │
└────────────┘   └────────────┘   └────────────┘

Effect of current.next = head;:

 head             current          temp
  ↓                ↓                ↓
┌────────────┐   ┌────────────┐   ┌────────────┐
│ value:   1 │   │ value:   2 │   │ value:   3 │
│ next: ────────►│ next: ─┐   │   │ next: null │
│            │◄───────────┘   │   │            │
└────────────┘   └────────────┘   └────────────┘

... the cycle is made!

The next two statements head = current; and current = temp; only move references:

                  head             current
                   ↓                ↓
┌────────────┐   ┌────────────┐   ┌────────────┐
│ value:   1 │   │ value:   2 │   │ value:   3 │
│ next: ────────►│ next: ─┐   │   │ next: null │
│            │◄───────────┘   │   │            │
└────────────┘   └────────────┘   └────────────┘

The next iteration will not touch this cycle anymore. The damage is permanent. The returned list will be:

                                   head
                                    ↓
┌────────────┐   ┌────────────┐   ┌────────────┐
│ value:   1 │   │ value:   2 │   │ value:   3 │
│ next: ────────►│ next: ─┐   │   │ next: ─┐   │
│            │◄───────────┘   │◄───────────┘   │
└────────────┘   └────────────┘   └────────────┘
  • Related