Reputation: 1136
Here is the definition of ListNote
class in LeetCode
:
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
For the code:
result = ListNode(0)
#result = 0 -> None
result_tail = result
#result_tail = 0 -> None
result_tail.next = ListNode(1)
#result_tail = 0 -> 1 -> None
#result = 0 -> 1 -> None
result_tail = result_tail.next
#result_tail = 1 -> None
#result = 0 -> 1 -> None
result_tail.next = ListNode(2)
#result_tail = 1 -> 2 -> None
#result = 0 -> 1 -> 2 -> None
result_tail = result_tail.next
#result_tail = 2 -> None
#result = 0 -> 1 -> 2 -> None
The values in comments are from my guessing. I cannot understand the step
result_tail = result_tail.next
result_tail = result
is pass by reference, so when result_tail
becomes 1 -> None
, result
should also become 1 -> None
. Why does result
still keep 0 -> 1 -> None
? And when result_tail
becomes 1 -> 2 -> None
, why does result
extend its tail to 0 -> 1 -> 2 -> None
?
result_tail = result_tail.next
is something like
result_tail = result.next.next
Can anyone tell me the logic here?
Upvotes: 35
Views: 109812
Reputation: 53
All above answers seems good. I am just adding up an example for the reader's understanding.
Input given : [[1,4,5],[1,3,4],[2,6]]
ListNode object description:
[ListNode{val: 1, next: ListNode{val: 4, next: ListNode{val: 5, next: None}}}, ListNode{val: 1, next: ListNode{val: 3, next: ListNode{val: 4, next: None}}}, ListNode{val: 2, next: ListNode{val: 6, next: None}}]
Hope you got the CRUX!
Upvotes: 3
Reputation: 161
For those reading this in the future: I wanted to debug linked list problems on a local environment so here is what I did.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def __repr__(self):
return "ListNode(val=" + str(self.val) + ", next={" + str(self.next) + "})"
def list_to_LL(arr):
if len(arr) < 1:
return None
if len(arr) == 1:
return ListNode(arr[0])
return ListNode(arr[0], next=list_to_LL(arr[1:]))
def reverseList(head: ListNode) -> ListNode:
prev = None
while head:
next_node = head.next
head.next = prev
prev = head
head = next_node
return prev
# test cases
t1 = list_to_LL([1, 2, 3, 4, 5]) #ListNode(val=1, next={ListNode(val=2, next={ListNode(val=3, next={ListNode(val=4, next={ListNode(val=5, next={None})})})})})
t2 = list_to_LL([1, 2]) #ListNode(val=1, next={ListNode(val=2, next={None})})
t3 = list_to_LL([])
# answers
print(reverseList(t1))
print(reverseList(t2))
print(reverseList(t3))
Upvotes: 16
Reputation: 63
First, thank you so much for posting this question. I worked on the same problem and saw this piece of code and was puzzled too. Then I followed some comments from leetcode and came here.
I realize that my problem was that I didn't have a pen and paper earlier. After I drew the linked list on the paper by following the loop, it turned out to be quite clear.
If you are still not clear about this, please try to draw the linked list by following the logic. Not sure if I got the right term here but below is my understanding.
To be honest, I do not think this is related to pass by reference or value. To me, this is just about two variables being assigned with the same value(memory location) at the beginning. Think of variables as storage of address. Address is the real memory location which is the start of some value. Later on, one variable(result_tail) kept getting reassigned to a different location and one(result) stays the same.
Result and result_tail both point to the location of 0|None before the while loop.
0|None
grew into 0->7|None
, then 0->7->0|None
and at last 0->7->0->8|None
by result_tail.next being assigned every time. Result_tail gets reassigned so value changed during each loop, but result points to the same location which is the 0->....
Thus the result.
Upvotes: 4
Reputation: 467
The short answer to this is that, Python is a pass-by-object-reference language, not pass-by-reference as implied in the question. It means that:
result
and result_tail
are two variables that happen to point at the same valueresult_tail.next = ListNode(1)
) will affect the value shown by result
result_tail
to another value will NOT affect the value of result
result_tail = result_tail.next
is assigning the next node of the node that is currently assigned by the variableThe following is an visualization of the values that are assigned to the variables (r
= result
, rt
= result_tail
):
result = ListNode(0)
#r
#0 -> None
result_tail = result
#r
#0 -> None
#rt
result_tail.next = ListNode(1)
#r
#0 -> 1 -> None
#rt
result_tail = result_tail.next
#r
#0 -> 1 -> None
# rt
result_tail.next = ListNode(2)
#r
#0 -> 1 -> 2 -> None
# rt
result_tail = result_tail.next
#r
#0 -> 1 -> 2 -> None
# rt
References for additional reading:
Upvotes: 27