赞
踩
此题涉及一个重要概念:哨兵结点。
哨兵节点广泛应用于树和链表中,通常以伪头、伪尾、特殊标记等形式存在。它存在的目的通常是使链表永不为空、永不无头、方便改变链表结构、或实现头部可删等。
这道题的思路是,写一个循环使head前进的同时一步步反转链表中的元素。具体思考过程如下:
首先,给链表加一个伪头(哨兵结点)dummy,这个结点指向原链表的表头。
然后,以链表[1→2→3→4→5]为例,进行三个改变链的指向的操作,如下图所示。
之后,链表就变成了[2→1→3→4→5]。然后head前进,重复这三个操作。
此时,链表就变成了[3→2→1→4→5]。然后head继续前进,重复,直到循环结束。
这里的箭头大家看了最好自己画一画体会一下,不然不是特别好理解。
Python3的代码实现如下:
- # Definition for singly-linked list.
- # class ListNode:
- # def __init__(self, val=0, next=None):
- # self.val = val
- # self.next = next
- class Solution:
- def reverseList(self, head: ListNode) -> ListNode:
- dummy = ListNode(0) # 这里dummy的value可以任意取,我取了0
- dummy.next = head # 指向原链表的头,相当于加了一个伪头,这个dummy就是哨兵结点
- while(head != None and head.next != None):
- dnext = dummy.next
- hnext = head.next
- # 下面的三行代码分别表示上面提到的三个操作
- dummy.next = hnext
- head.next = hnext.next # hnext.next是当前结点的下下个结点
- hnext.next = dnext
- return dummy.next

这里有两个点要注意一下。
最终的执行用时击败60%,内存消耗击败45%。
另外在LeetCode评论区看到了另一个非常厉害的解题方法,来自gaussic大神。这个方法巧妙地利用了Python3在多元赋值时等号右边值不会随赋值而改变的性质,完美解决了上面我用两行代码、两个额外空间才解决的问题。太妙了!看的我直呼内行...
- # Definition for singly-linked list.
- # class ListNode:
- # def __init__(self, val=0, next=None):
- # self.val = val
- # self.next = next
- class Solution:
- def reverseList(self, head: ListNode) -> ListNode:
- p, rev = head, None
- while p:
- rev, rev.next, p = p, rev, p.next
- return rev
最终的执行用时击败82%,内存消耗击败54%。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。