简体   繁体   English

了解while循环条件,以了解如何在链表中查找中间节点

[英]Understanding the while loop condition in how to find the middle node in a linked list

I don't fully understand the while loop condition for the "find the middle of linked list" question on leetcode: 我不完全了解leetcode上的在链表中间找到”问题的while循环条件:

Given a non-empty, singly linked list with head node head, return a middle node of linked list. 给定一个带有头节点head的非空单链表,返回链表的中间节点。

If there are two middle nodes, return the second middle node. 如果有两个中间节点,则返回第二个中间节点。

For the while loop, I thought the condition would be 对于while循环,我认为条件是

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: 这是带有正确while循环的完整代码:

# 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

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. 初始化将中间( first )和结束( last )指针设置为您最初唯一了解的内容:列表的开始。 The body of the loop steps them forward: first = first.next moves one step ahead while last = last.next.next moves two steps ahead. 循环的主体将它们向前移动: first = first.next向前移动了一步,而last = last.next.next向前移动了两步。 Since last is always ahead of first , the is no need to check if first can move forward. 由于last总是在first ,因此不需要检查first可以前进。 Instead, the condition of the loop checks that both of the references used in stepping last are non- None : while last and last.next: . 取而代之的是,循环的条件将检查在执行last使用的两个引用都是非None while last and last.next:

Notice that if the list has one element, last will not move since last.next is None . 请注意,如果列表具有一个元素,由于last.nextNonelast将不会移动。 However, with two elements, last will move, and so will first . 但是,有了两个元素, last将会移动, first也会移动。 The result is that the condition for picking the second middle from a list with an even number of elements is satisfied. 结果是满足了从具有偶数个元素的列表中选择第二个中间元素的条件。

Just draw it out and it will be obvious. 只需将其绘制出来,就会很明显。 Consider both versions: 考虑两个版本:

A - B - C A-B-C

first / last / last.next
A       B      C  
B       None    

A - B - C - D A B C D

first / last / last.next
A       B      C  
B       D      None

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM