leetcode 第206题 反转链表
简单题,但是其中的递归法不太好理解
方法一、迭代法
迭代法非常简单,两个变量,一个记录上一个节点,一个记录当前节点。但是有个注意的点,进入循环后第一步就是要记下原来cur.next的值,因为后面会改变但是又要通过它前进所以要先记录下来:
def reverseList(self, head: ListNode) -> ListNode:
pre, cur = None, head
while cur:
# 注意一定要记下原来的cur.next
or_cur_next = cur.next
# 这里改变了cur.next但后面还要用
cur.next = pre
pre = cur
cur = or_cur_next
return pre
方法二、递归
递归比较难懂,因为它反过来了,通过内部调用的函数得到了新的head,然后将这个head的next指向了当前的节点,记住了这一点就很好理解了,还有就是要记得将初始头节点的next指向None,否则会形成环!
我自己的代码耗时较久,用到了全局变量记录原来的尾节点,因为这个会成为答案,还有就是为了将原来的头节点的next指向空我在递归结束之后单独对他进行了操作,官方是直接在递归里面实现了这一个的
我自己的代码:
def reverseList(self, head: ListNode) -> ListNode:
if not head:
return
def help(root):
if root.next == None:
# 用全局变量记录了新的头节点
global last_node
last_node = root
return root
# 这里是核心,利用递归生成的是新的头
new_head = help(root.next)
# 本函数的变量root成了被赋的那个值
new_head.next = root
# 注意就是直接返回自己,root本身没有改变
# 递归的目的就是让上一层函数得到我
return root
# help返回的是原来的头现在的尾
new_last_node = help(head)
new_last_node.next = None
return last_node
官方代码:
递归,这个才是真正的递归的使用,将大问题转换成小问题不断的化解,然后完善终止条件等细节 ,递归就是应该将代码划分为三部分
- 终止条件
- 递归函数
- 操作部分 : 核心,知道每一个小步究竟是做什么
def reverseList(self, head: ListNode) -> ListNode:
# 最后传进来的是head.next,这个东西没有.next,不判断的话会报错
if head is None or head.next is None:
return head
p = self.reverseList(head.next)
head.next.next = head
# 直接将head.next设置为空
head.next = None
return p