反转整个链表
先直接上代码:
class Solution20:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head or not head.next:
return head
last = self.reverseList(head.next)
head.next.next = head
head.next = None
return last
怎么理解呢?我们一行一行的来看!
首先是badcase部分,当链表为空,或者只有一个节点的时候,直接返回就可以了,也没什么好反转了!
if not head or not head.next:
return head
最后三行就很神奇的,初次刷题是懵的状态,看了东哥的解释才回过神来。对于递归的问题,最关键的是明确递归函数的定义。在上面的函数中,reverseList表示给定一个链表,对其进行反转,并输出反转后的链表的头节点。
然后来看last是个什么东西:
last = self.reverseList(head.next)
现在离我们想要的结果还缺把2指向1,于是我们写了:
head.next.next = head
以及把head指向空:
head.next = None
反转链表的前N个节点
延续上面的思路,明确递归函数的定义。在这个问题里,显然我们的递归函数需要定义为:给定一个链表和N,反转链表的前N个节点,并返回反转以后的链表的头节点。
def reverseN(self, head: Optional[ListNode], N: int) -> Optional[ListNode]:
global successor
if N == 1:
successor = head.next
return head
tmp = self.reverseN(head.next, N-1)
head.next.next = head
head.next = successor
return tmp
因为这个问题不是反转整个链表,最后head.next不再是为null啦!所以要记录一个被打断的点successor,作为head.next。其他的思路和前面一样。
反转链表的某一部分
代码简单的可怜:
class Solution:
def reverseN(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
"""反转链表的前N个节点,并返回反转之后的链表的头节点"""
successor = None
if n == 1:
successor = head.next
return head
last = self.reverTopN(head.next, n-1)
head.next.next = head
head.next = successor
return last
def reverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]:
if left == 1:
return reverseN(head, left, right)
head.next = self.reverseBetween(head.next, left-1, right-1)
return head
第一个函数就不解释了,就是反转链表的前N个节点的函数。
badcase也很好理解,如果left=1的话,相当于反转前right个节点,直接调用self.reverseN就可以了。
if left == 1:
return self.reverseN(head, left, right)
那如果left != 1呢,如果我们把head.next作为被反转的主体,left和right相应的都要-1才能对得上,直接调用就行了。
参考资料
- 《labuladong的算法小抄》