链表反转,就是头节点的移动。反转链表头节点的后继节点就是反转链表上一步的头节点,反转链表当前的头节点则为原链表的当前头节点,然后将原链表当前的头节点向后移动一个位置,一直重复这个过程。
递归写法
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head:
return
def f(reverse_head, head): #递归写法
if not head:
return reverse_head
reverse_head, reverse_head.next, head = head, reverse_head, head.next
return f(reverse_head, head)
return f(None, head)
迭代写法
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
if not head:
return
def f(reverse_head, head): #迭代式
while head:
reverse_head, reverse_head.next, head = head, reverse_head, head.next
return reverse_head
return f(None, head)
leetcode上的反转链表2:反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。1<=m<=n<=链表长度。在一趟扫描中,找到位置m的前驱节点,n 的后继节点,就可以很方便的将反转的部分串起来。
class Solution:
def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
count = 1
node = head
if m == n: #m,n指向同一个节点,一个节点反转就是其本身,所以直接返回
return head
if m == 1: #从头节点开始反转,需特殊处理
start_node = head
pre_node = None
while 1:
if count == m - 1: #要找m的前驱节点,所以计数到m-1
pre_node = node
start_node = node.next
if count == n:
end_node = node
post_node = node.next #位置n的后继节点
break
node = node.next
count += 1
#缓存反转后的尾节点,并将n的后继置为None,方便反转链表
tmp_tail, end_node.next = start_node, None
def reverse(reverse_head, start_node): #反转
if not start_node:
return reverse_head
reverse_head, reverse_head.next, start_node= start_node, reverse_head, start_node.next
return reverse(reverse_head, start_node)
tmp_head = reverse(None, start_node)
if pre_node:
pre_node.next, tmp_tail.next = tmp_head, post_node
return head
else:
tmp_tail.next = post_node
return tmp_head