我想知道如何在Python语言中使用递归方法来反转单链表.

这是LeetCode问题206. Reverse Linked List:

给定单链接列表的第head位,反转该列表并返回the reversed list.

例1:

enter image description here

Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]

大多数人使用迭代方法,这是非常classic 且易于理解的方法.然而,我遇到了一个令我困惑的递归方法:

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # recursive call
        if not head:
            return None

        newHead = head
        if head.next:
            newHead = self.reverseList(head.next)
            head.next.next = head
        head.next = None
        print(newHead)
        return newHead

例如,如果我输入[1,2,3],我会手动计算出如下过程,这看起来似乎是正确的,但我不能说服自己,它将通过递归调用reverselist返回正确的东西.你能告诉我为什么吗?非常感谢!

my draft of what the above recursive calls would work

推荐答案

以下是如何可视化链接列表1→2→3的逆转:

我们从以下几个方面开始:

 head
  │
┌─┴─────────┐   ┌───────────┐   ┌───────────┐
│ val: 1    │   │ val: 2    │   │ val: 3    │
│ next: ────────┤ next: ────────┤ next: None│
└───────────┘   └───────────┘   └───────────┘

第一个递归调用接收head.next,并将有自己的本地名称.为了将这些本地名称与我们在reverseList的原始执行中已经读到的名称区分开来,我将在名称中添加重音符号,其中Accens的数量表示递归深度.因此,在第一次递归调用时,我们可以将情况可视化为:

 head            head'
  │               │
┌─┴─────────┐   ┌─┴─────────┐   ┌───────────┐
│ val: 1    │   │ val: 2    │   │ val: 3    │
│ next: ────────┤ next: ────────┤ next: None│
└───────────┘   └───────────┘   └───────────┘

在第二级递归调用中:

 head            head'           head'' newHead''
  │               │               │      │
┌─┴─────────┐   ┌─┴─────────┐   ┌─┴──────┴──┐
│ val: 1    │   │ val: 2    │   │ val: 3    │
│ next: ────────┤ next: ────────┤ next: None│
└───────────┘   └───────────┘   └───────────┘

这个二级递归执行不会进入if块,只会将head''next属性设置为None(它已经这样做了)并返回newHead''.

返回第一次返回的引用赋值为newHead'的递归执行,因此我们得到以下结果:

 head            head'           newHead'
  │               │               │
┌─┴─────────┐   ┌─┴─────────┐   ┌─┴─────────┐
│ val: 1    │   │ val: 2    │   │ val: 3    │
│ next: ────────┤ next: ────────┤ next: None│
└───────────┘   └───────────┘   └───────────┘

在这个递归执行中,这是我们第一次执行head.next.next = head,作用于head'.因此,我们得到:

 head            head'           newHead'
  │               │               │
┌─┴─────────┐   ┌─┴─────────┐   ┌─┴─────────┐
│ val: 1    │   │ val: 2    │   │ val: 3    │
│ next: ────────┤ next: ────────┤ next: ┐   │
│           │   │           ├───────────┘   │
└───────────┘   └───────────┘   └───────────┘

然后head'next属性得到None:

 head            head'           newHead'
  │               │               │
┌─┴─────────┐   ┌─┴─────────┐   ┌─┴─────────┐
│ val: 1    │   │ val: 2    │   │ val: 3    │
│ next: ────────┤ next: None│   │ next: ┐   │
│           │   │           ├───────────┘   │
└───────────┘   └───────────┘   └───────────┘

最后,第一次递归执行返回newHead'.

原始执行接收此引用并将其分配给自己的newHead:

 head                            newHead
  │                               │
┌─┴─────────┐   ┌───────────┐   ┌─┴─────────┐
│ val: 1    │   │ val: 2    │   │ val: 3    │
│ next: ────────┤ next: None│   │ next: ┐   │
│           │   │           ├───────────┘   │
└───────────┘   └───────────┘   └───────────┘

同样,执行head.next.next = head:

 head                            newHead
  │                               │
┌─┴─────────┐   ┌───────────┐   ┌─┴─────────┐
│ val: 1    │   │ val: 2    │   │ val: 3    │
│ next: ────────┤ next: ┐   │   │ next: ┐   │
│           ├───────────┘   ├───────────┘   │
└───────────┘   └───────────┘   └───────────┘

最后,将head.next设置为None,并返回newHead:

                                 (returned)
                                  │
┌───────────┐   ┌───────────┐   ┌─┴─────────┐
│ val: 1    │   │ val: 2    │   │ val: 3    │
│ next: None│   │ next: ┐   │   │ next: ┐   │
│           ├───────────┘   ├───────────┘   │
└───────────┘   └───────────┘   └───────────┘

...这是颠倒了的名单.

希望这能澄清这一点.

Python相关问答推荐

将嵌套列表的字典转换为数据框中的行

如何在PIL、Python中对图像应用彩色面膜?

是pandas.DataFrame使用方法查询后仍然排序吗?

Polars:使用列值引用when / then表达中的其他列

Odoo -无法比较使用@api.depends设置计算字段的日期

使用pandas、matplotlib和Yearbox绘制时显示错误的年份

LAB中的增强数组

如何让 turtle 通过点击和拖动来绘制?

如何在msgraph.GraphServiceClient上进行身份验证?

如何计算两极打印机中 * 所有列 * 的出现次数?

Select 用a和i标签包裹的复选框?

Pytest两个具有无限循环和await命令的Deliverc函数

图像 pyramid .难以创建所需的合成图像

' osmnx.shortest_track '返回有效源 node 和目标 node 的'无'

Python解析整数格式说明符的规则?

如何使用Python以编程方式判断和检索Angular网站的动态内容?

梯度下降:简化要素集的运行时间比原始要素集长

如何在Python中找到线性依赖mod 2

如何使用Pandas DataFrame按日期和项目汇总计数作为列标题

使用Python TCP套接字发送整数并使用C#接收—接收正确数据时出错