前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图解精选 TOP 面试题 005.1 | 反转链表之递归求解

图解精选 TOP 面试题 005.1 | 反转链表之递归求解

作者头像
江不知
发布2019-12-19 15:43:30
5460
发布2019-12-19 15:43:30
举报
文章被收录于专栏:编程拯救世界编程拯救世界

该系列题目取自 LeetCode 精选 TOP 面试题列表:https://leetcode-cn.com/problemset/top/

题目描述

LeetCode 206. 反转链表:https://leetcode-cn.com/problems/reverse-linked-list/

反转一个单链表。

示例:

代码语言:javascript
复制
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

进阶:

你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

解题思路

在上一篇《图解精选 TOP 面试题 005 | 反转链表之迭代求解》中,我们介绍了该题的迭代求解法,本篇再说说如何进行递归求解。

首先,在写代码前,我们需要先进行「递归设计」,即明确三点:

  1. 递归函数的作用
  2. 何时结束递归
  3. 何时进行递归调用

函数作用

递归函数的作用为:改变当前节点下一个节点的 next 指针,使其指向当前节点

听起来有点拗口,用代码表示就是这样的:

代码语言:javascript
复制
# 当前节点的下一个节点
next_node = head.next
# 改变下一个节点的指针
next_node.next = head

我们用这样的方式就完成了某两个节点之间指向的反转

除此之外,为了防止链表循环,我们还要切断当前节点的 next 指向,即设 head.next 为空。

何时结束

当节点为空或节点的 next 节点为空时,返回当前节点。

这样的结束条件我们可以理解为:空节点或只有一个节点时,它的反转就是其本身

何时调用

在迭代法中,我们为了反转与遍历,不断地保存上一个节点与下一个节点,整个过程显得小心翼翼。而在递归中,我们先根据链表原有的顺序利用递归将节点依次入栈,之后再层层弹出,从而反转节点之间的指向。

因此,在节点不为空且节点的下一个节点不为空时,我们进行递归调用,以此不断地将当前节点的下一个节点压入栈区,直至链表尾部。

反转过程演示

以题目中的 1->2->3->4->5->NULL 为例,整个反转过程如下:

反转过程

具体实现

Python

代码语言:javascript
复制
# 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:
        if head is None or head.next is None:
            return head

        # 不断往后获取节点
        cur = self.reverseList(head.next)
        # 反转节点指向
        next_node = head.next
        next_node.next = head
        # 切断当前节点的 next 指向
        head.next = None

        return cur

Go

代码语言:javascript
复制
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func reverseList(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }

    cur := reverseList(head.Next)
    nextNode := head.Next
    nextNode.Next = head
    head.Next = nil

    return cur
}

复杂度

  • 时间复杂度 ,n 为链表长度。
  • 空间复杂度 ,由于使用递归调用,需要考虑调用栈的情况。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程拯救世界 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目描述
  • 解题思路
    • 函数作用
      • 何时结束
        • 何时调用
        • 反转过程演示
        • 具体实现
          • Python
            • Go
            • 复杂度
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档