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的情况了。