206. 反转链表

题目链接

https://leetcode.cn/problems/reverse-linked-list/description/

解题思路

按照我们解递归的一般思路,首先确定参数和返回值。

从题意可以看出,参数是给定一个链表的头结点,返回值是一个逆序的链表。

然后,缩小问题规模的方式,在链表中,肯定就是处理当前结点,把后续结点交给递归函数处理。

然后,我们确定本层要做什么。既然递归函数的返回值是逆序好的链表,那本层需要做的事情就是,将本层的结点接在逆序好的链表的末尾。

最后,我们判断一下递归出口。如果本层只剩下一个结点,或者本层直接就是None, 那么直接返回本层即可。

代码1

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution:
    def reverseList(self, head):
        if head is None or head.next is None:
            return head
        last = self.reverseList(head.next)
        tail = last
        while tail:
            if tail.next is None:
                break
            tail = tail.next
        tail.next = head
        head.next = None
        return last

代码2

 

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if head is None or head.next is None:
            return head
        next_head = self.reverseList(head.next)
        head.next.next = head
        head.next = None
        return next_head

 

这两种实现有什么不同呢?在于我们找到head该接在哪里的方式不同。

代码1是完全践行了递归程序设计,把reverseList的返回值当成了完全不相干的一个逆序链表,通过遍历的方式找到了最后,然后把head接在了最后。

而代码2,考虑到了实际情况。比如1,2,3,4,5。 逆序之后,对于第一层递归来说,1是1,2,3,4,5在reverseList处理之后是5,4,3,2.

但,此时,1的next还是2. 1的val和next都没有代码去修改,所以当然是2.

所以我们可以直接: head.next.next = head。 这样就将2指向了1.

但此时1的next还指向了2. 即,如果我们从5开始往后遍历,就变成了:5->4->3->2->1->2->1......

所以我们应该让1指向None, 打破这个环。

这就是代码2的情况了。

posted @ 2023-01-03 11:10  BJFU-VTH  阅读(22)  评论(0编辑  收藏  举报