反转链表的常用方法

这是一道经常出现在Leetcode和面试中的链表基础题:

 

给定指向链表头节点的指针,任务是反转链表。我们需要通过更改节点之间的链接来反转列表。

例如:

如果只是简单的反转链表,我们可以创建一个列表并遍历链表,将遍历的元素储存到列表当中,最后倒序的从列表中提取元素并建立一个全新的链表。然而,这种方法的问题在于需要额外的空间去存储链表中的元素,且至少需要遍历两次(一次储存元素,一次倒序提取元素),这显然不是最聪明的做法。

今天我们就来分享几个简单好理解的,且空间复杂度为O(1)的算法:

迭代法 :

  1. 初始化三个指针 prev 为 NULL,curr 为 head,next 为 NULL。
  2. 遍历链表。在循环中,执行以下操作。

        //在改变当前节点的下一个节点之前,先获取到下一个节点,即next = curr->next

        //然后改变当前节点的下一个节点,也就是实际反转,即curr->next = prev 

        // 将 prev 和 curr 向前移动一步 

以下是该方法的Python代码实现: 

时间复杂度: O(n) 
额外空间: O(1) 

递归法:

  1. 将列表分为两部分 - 第一个节点和链表的其余部分。 
  2. 对链表的其余部分调用反转。
  3. 将第一个节点连接到反转后的其余部分。
  4. 重新定义头指针。

以下是该方法的Python代码实现:

  

由于递归方法,内部有一个栈空间,因此递归法的实际空间应为O(n),某些情况下可以认为是O(1)

时间复杂度: O(n)

空间复杂度: O(n)  

除了上述的两种最常见的方法,还有一些有趣的方法例如:尾递归 (O(n), O(1)),头递归 (O(n), O(n)), 以及双指针 (O(n), O(1))。

 完整代码实现下载:

(包含各种语言:C、Python、Java、C++、C# 等均有示例)

免费​资源下载:反转链表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值