Reputation: 403
I don't fully understand the while
loop condition for the "find the middle of linked list" question on leetcode:
Given a non-empty, singly linked list with head node head, return a middle node of linked list.
If there are two middle nodes, return the second middle node.
For the while
loop, I thought the condition would be
while first and last.next:
But when I do that, I receive an error that says
AttributeError: 'NoneType' object has no attribute 'next'
The condition statement is supposed to be
while last and last.next:
I don't understand why. Here is the entire code with the correct while loop:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def middleNode(self, head):
first = last = head
while last and last.next:
first = first.next
last = last.next.next
return first
Upvotes: 3
Views: 954
Reputation: 114320
The idea behind the algorithm is that you don't know where the end of the list is. However, if you step one pointer twice as fast as the other, it will reach the end just as the other reaches the middle.
The initialization sets the middle (first
) and end (last
) pointers to the only thing you know initially: the start of the list. The body of the loop steps them forward: first = first.next
moves one step ahead while last = last.next.next
moves two steps ahead. Since last
is always ahead of first
, the is no need to check if first
can move forward. Instead, the condition of the loop checks that both of the references used in stepping last
are non-None
: while last and last.next:
.
Notice that if the list has one element, last
will not move since last.next
is None
. However, with two elements, last
will move, and so will first
. The result is that the condition for picking the second middle from a list with an even number of elements is satisfied.
Upvotes: 5
Reputation: 1437
Just draw it out and it will be obvious. Consider both versions:
A - B - C
first / last / last.next
A B C
B None
A - B - C - D
first / last / last.next
A B C
B D None
Upvotes: 0