【剑指offer】JZ24-反转链表-Python解法

1.题目描述

2.解题思路(Python版)

方法一:迭代

思路:

链表反转即将每个结点的指针从向后变为向前,所以最简单的办法就是遍历原始链表,将遇到的结点指针一一逆向即可,但这样做有一个缺陷,如果我们将当前结点原本向后的指针修改为指向前一个结点的指针,那将会造成链表断裂,从后一个结点开始的链表信息丢失。为了弥补这个缺陷,我们应该额外存储下一个结点。具体实现思路如下:

1.设置两个指针,一个表示上一个结点的指针(pre,初始值为空),一个表示当前结点的指针(cur);

2.遍历整个链表,每访问一个结点,先将下一个结点的信息存储到temp中,然后断开当前结点与后面结点的指针,将当前结点指向前一个结点;

3.轮换当前指针与上一个指针,让它们分别指向下一个结点及下一个结点的前序结点,完成一次迭代;

4.迭代的结束条件:cur指向的下一个结点为空,即已遍历到原始链表的尾结点处。

参考代码:

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @return ListNode类
#
class Solution:
    def ReverseList(self , head: ListNode) -> ListNode:
        # write code here
        pre = None   #若原始链表为空链表,则直接输出一个空链表
        cur = head   #存储头结点
        while cur: 
            temp = cur.next       #将当前结点的下一个结点保存下来,避免链表断裂后丢失后续结点
            cur.next = pre        #原链表头结点变为反转后的尾结点,其next域变为空
            pre = cur             #前一个结点更新为当前结点
            cur = temp            #指针移动到下一个结点上
        return pre

在实现过程中存在一个疑问:为什么pre最后输出的不是原始链表的尾结点(即反转后的链表的头结点),而是整个反转后的链表,询问GPT老师后得到以下回答:在链表中,结点不仅仅包含一个值,还包含一个指向下一个结点的引用。因此,当你返回链表的头结点时,实际上你返回的是一个包含整个链表结构的结点。

复杂度:

时间复杂度O(N):遍历链表一次,N是链表的长度;

空间复杂度O(1):常数级变量,无额外辅助空间使用。

方法二:递归

思路:

1.递归条件:逆转当前结点与其后整个子链表之间的指针,然后继续对子链表做上述操作;

2.基线条件(递归结束条件):当前处理的链表头结点为空,或头结点的Next域为空

参考代码:

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 
# @return ListNode类
#
class Solution:
    def ReverseList(self , head: ListNode) -> ListNode:
        # write code here
        if head is None or head.next is None:    #基线条件
            return head
        newHead = self.ReverseList(head.next)     #对子链表做反转
        head.next.next = head    #逆转当前节点
        head.next = None    #尾结点设为空结点
        return newHead

复杂度:

时间复杂度O(N):遍历链表一次,N是链表的长度;

空间复杂度O(N):递归栈深度为链表长度N,相较于迭代方法,花费更多空间。

除以上两种方法外,还可以借助JZ6中的方法,将链表从尾到头打印后放置在数组中,再将数组转为链表即可。使用如下方法可将数组转换为链表:

def createNode(nums):
    if len(nums) == 0:
        return None
    head = ListNode(nums[0])
    cur = head
    for i in range(1, len(nums)):
        cur.next = ListNode(nums[i])
        cur = cur.next
    return head

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值