提问者:小点点

为什么prev、curr、next对于反向链接List问题的迭代解决方案是必要的?


链表的经典入口问题:给定单链表的头部,反转列表,返回反转列表。

例如,输入:head=[1,2,3,4,5]输出:[5,4,3,2,1]

Python中一个非常典型的解决方案是

def reverseList(self, head):
    prev = None
    curr = head

    while curr:
        next = curr.next
        curr.next = prev
        prev = curr
        curr = next
    
    return prev

在我看来,下面的也会起作用

def reverseList(self, head):
        curr=head
        while curr.next:
            tmp=curr
            curr=curr.next
            curr.next=tmp
        
        return curr

我只使用2(tmp, curr)而不是3(prev,curr,next)'变量'(如果描述它们的名称错误,请纠正我)。我知道我没有考虑链表的末尾应该指向无。然而,它不应该给出与建议的解决方案相似的结果吗?但是,我得到了第二个运行时错误?出了什么问题?


共2个答案

匿名用户

让我们看看在具有值1、2和3的链表的第二个代码版本中会发生什么。

在循环开始之前,我们有这样的情况:

 head, 
 curr
  ↓        
┌──────────┐   ┌──────────┐   ┌──────────┐ 
│ data: 1  │   │ data: 2  │   │ data: 3  │
│ next: ─────► │ next: ─────► │ next:None│
└──────────┘   └──────────┘   └──────────┘

第一次迭代后,更新了一个next引用:

 head           curr
  ↓              ↓
┌──────────┐   ┌──────────┐   ┌──────────┐ 
│ data: 1  │   │ data: 2  │   │ data: 3  │
│ next: ─────► │ next: ─┐ │   │ next:None│
└──────────┘   └────────│─┘   └──────────┘
  ↑      ▲              │
 tmp     └──────────────┘

这看起来已经不对了,因为我们丢失了对第三个节点的任何引用,该节点已变得无法访问。因此,一旦更新了next属性,所有完成逆转的希望都失去了。

但也要注意在第二次迭代中,curr是如何在列表中倒退的,因为它遵循更新的next引用。这不是应该发生的事情。curr应该继续前进。然后它将头部的next属性设置为第二个节点,但这已经是这种情况了(这里没有逆转!)。因此curr将无休止地绕圈子。

与第一个工作版本相比,在进行元组赋值时可以少用一个变量:

    def reverseList(self, head):
        curr = head
        prev = None
        while curr:
            curr.next, prev, curr = prev, curr, curr.next
        return prev

要将其简化为一个变量(head),您可以使用递归解决方案:

    def reverseList(self, head):
        if not head or not head.next:
            return head
        head.next.next, head.next, head = head, None, self.reverseList(head.next)
        return head

匿名用户

list = [1,2,3,4,5]
list.reverse()
print(list) // [5, 4, 3, 2, 1]
def reverseMyList(list):
    listReversed = []
    for i in list:
            listReversed.insert(0, i)
    return listReversed