链表的经典入口问题:给定单链表的头部,反转列表,返回反转列表。
例如,输入: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)'变量'(如果描述它们的名称错误,请纠正我)。我知道我没有考虑链表的末尾应该指向无。然而,它不应该给出与建议的解决方案相似的结果吗?但是,我得到了第二个运行时错误?出了什么问题?
让我们看看在具有值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