Reputation: 193
I'm looking at This LeetCode Question about LinkedList and there's something I don't understand about the answer.
In the code below, I have copied the answer from above and added a comment in the place I want to refer to:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def addTwoNumbers(l1,l2):
dummyHead = ListNode(0)
curr = dummyHead
carry = 0
while l1 != None or l2 != None or carry != 0:
l1Val = l1.val if l1 else 0
l2Val = l2.val if l2 else 0
columnSum = l1Val + l2Val + carry
carry = columnSum // 10
newNode = ListNode(columnSum % 10)
#####################
curr.next = newNode #
curr = newNode # <- Part 1
##############################
l1 = l1.next if l1 else None # <- Part 2
l2 = l2.next if l2 else None #
##############################
return dummyHead.next
l1 = ListNode(1)
l2 = ListNode(2)
print(addTwoNumbers(l1=l1,l2=l2).val)
Part 1
, why set curr.next
to newNode
and then completely overwrite it with curr = newNode
? I checked, and it seems like it overwrites the value completely, and thus removing the next
in curr
.Part 2
, doesn't the following line: l1 = l1.next
overwrite everything yet again?dummyHead.next
works? This value wasn't modified, it's just an empty list in the beginningI tried to debug but I still haven't gotten much out of it. I'm trying to learn LinkedList from this example and would appreciate any help. Huge thanks ahead!
Upvotes: 0
Views: 357
Reputation: 350300
why set
curr.next
tonewNode
and then completely overwrite it withcurr = newNode
?
These are two different type of assignment. The first -- assigning to curr.next
-- mutates whatever object that curr
is referencing. The second -- curr = newNode
-- merely changes what curr
references to. It doesn't mutate the data structure. It may help to visualise what happens. Let's say curr
references a ListNode
instance with value 1:
curr
│
┌─┴──────────┐
│ val: 1 │
│ next: None │
└────────────┘
And newNode
was just created with a value 2:
curr newNode
│ │
┌─┴──────────┐ ┌─┴──────────┐
│ val: 1 │ │ val: 2 │
│ next: None │ │ next: None │
└────────────┘ └────────────┘
Then the first assignment -- curr.next = newNode
will accomplish this:
curr newNode
│ │
┌─┴──────────┐ ┌─┴──────────┐
│ val: 1 │ │ val: 2 │
│ next: ──────────┤ next: None │
└────────────┘ └────────────┘
And the second assignment, leads to this state:
curr newNode
│ │
┌────────────┐ ┌─┴────┴─────┐
│ val: 1 │ │ val: 2 │
│ next: ──────────┤ next: None │
└────────────┘ └────────────┘
The same would have happened, if the second assignment would have been curr = curr.next
, since at that point curr.next
and newNode
reference the same object. This should also explain the rationale for your second point concerning l1 = l1.next
. This merely traverses one step through a linked list with a variable. It doesn't affect that linked list itself.
How does returning
dummyHead.next
works? This value wasn't modified, it's just an empty list in the beginning.
The list was modified. But it happened via a different variable... curr
. Note how initially curr
references the same object as dummyHead
, and then in the loop, the assignment to curr.next
is setting the next
attribute that dummyHead
references, so that now dummyHead.next
references a list with one element. And curr
will move on to reference that element, and again set its next
attribute, making that linked list having 2 nodes, ...etc
Upvotes: 1