输入一个链表,反转链表后,输出新链表的表头。
时间o(n),空间o(1)
迭代解法
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
if not pHead:
return pHead
p = pHead
q = p.next
p.next=None #摘掉头
while q != None:
t = q.next #记录下一个元素
q.next=p #新摘掉的元素放在p前面
p=q #更新头指针p
q=t #继续原链表中下一个元素
return p
主要是摘头,插头的逻辑关系要搞清楚,头脑不清就容易出错。t和q指针的移动,一定是t先于q一步
递归解法
时间O(n), 空间O(n)
递归版本稍微复杂一些,其关键在于反向工作。假设列表的其余部分已经被反转,现在我该如何反转它前面的部分?假设列表为:n1 → … → nk-1 → nk → nk+1 → … → nm → Ø
若从节点 nk+1 到 nm 已经被反转,而我们正处于 nk。
n1 → … → nk-1 → nk → nk+1 ← … ← nm
我们希望 nk+1 的下一个节点指向 nk。
所以,
nk.next.next = nk;
要小心的是 n1 的下一个必须指向 Ø 。否则链表中可能会产生循环。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
'''
逆置后最后一个元素为头结点,故先走到最后一个元素,记录该元素,最后返回他作为头指针
中间执行链表逆置的步骤:对链表中除了最后一个元素的任意两个元素(p, p.next)其逆置过程
为p.next.next = p, p.next = None
只有两个元素时链表逆置过程为:p.next.next = p; p.next = None
'''
def reverse(p: ListNode):
if p == None or p.next == None:
return p
q = reverse(p.next)
p.next.next = p
p.next = None
return q
return reverse(head)