If I understood well your question what is troubling you is mutability (and pointers)
Given your method:
public static ListNode deleteDuplicates(ListNode head) {
ListNode result = head;
if (head == null)
return head;
// System.out.println(ListNodetoString(result));
while (result.next != null) {
if (result.val == result.next.val)
result.next = result.next.next;
else
result = result.next;
}
return head;
}
(simplified response),
the memory, at the beginning of the method, contains just the head
pointer to the list:
1-next->1-next->2
↑
head:----┘
when you do:
ListNode result = head;
you're creating a pointer to the same value as head is pointing, like:
1-next->1-next->2
↑
head:----┘
result:--┘
Then you start iterating the list, and the branches of the if condition cause different effects.
When result.val == result.next.val
is true you modify the internal state of the ListNode
using
result.next = result.next.next;
What it does, is changing the pointer of the list, as you are referencing the field .next
of the value whom result
is pointing, like:
1-next--┐
↓
1-----next----->2
↑
head:----┘
result:--┘
as result.next was changed, the 2nd node (the 1
in first line) is not referenced anymore by any pointer.
Then your while
start again, having the if condition false, at this point the method does:
result = result.next;
In this way you are changing what result
is pointing to, like:
1-next┐
↓
1-next->2
↑ ↑
head:----┘ |
result:----------┘
So when you return head
you are returning the value head
is pointing to, the first element of the list. Meanwhile during the iteration result
change each time the if return a false, going on if your initial list was:
1-next->1-next->2-next->3
The next iteration would change result again like:
1-next┐
↓
1-next->2-next->3
↑ ↑
head:----┘ |
result:------------------┘
But head
always remain to the top element.
The fact is that you don't need a return value, for what I understood from your code, it would works also as:
public static void deleteDuplicates(ListNode head) {
ListNode result = head;
if (head == null)
return;
// System.out.println(listNodetoString(result));
while (result.next != null) {
if (result.val == result.next.val)
result.next = result.next.next;
else
result = result.next;
}
}
Then you can try it with something like:
ListNode list = new ListNode(1, new ListNode(1, new ListNode(2, null)));
deleteDuplicates(list);
System.out.println(listNodetoString(list));
That's because in this way list
is pointing also to the first value of the list, so at the beginning of the method the memory is something like:
list:----┐
↓
1-next->1-next->2
↑
head:----┘