反转链表 递归与非递归实现
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]输出:[2,1]
示例 3:
输入:head = []输出:[]
思路:
反转链表!典中典!仍记得在我第一天刷题的时候,就做过这个题,辗转反侧,苦思冥想,不知道怎么做……现在看来反转链表是非常简单啦,而且也是面试基础高频题,主要有两种方法,一个是递归法,另一个是非递归(迭代法)
迭代法比较简单,但递归法比较巧妙。因此我都讲一下~而且我还是推荐用递归法,因为后面对于反转链表有其他变式(我记得有反转前n个节点,反转中间n个节点等,后面看看有没有机会写到),对于这些变式在递归法的基础上很好改。
迭代法:
其实很好理解,我们三个指针:pre,cur,next来共同遍历给定链表,每次让cur指向pre,通过cur和net的位置进行指针移动,等遍历到最后,整个链表的指向就都改变了。思路比较简单,直接看代码即可。
递归法:
我们明确递归函数reverseList,它的功能是传入要反转的链表头结点head,传出反转后的新头结点。
那么对于传入的头结点,我们取出第一个节点来,把剩下的节点传入递归函数,就可以得到剩下的节点反转后的结果,再把第一个节点连接到尾部,就得到了完整的反转后的链表。
代码:
迭代法:
class Solution(object):
def reverseList(self, head):
pre = None
cur = head
net = None
while (cur):#cur在链表主体上游走,cur和net在它两边
net = cur.next#每次先定义好net的位置
cur.next = pre#改变这一段的指针指向
pre = cur#通过cur和net的位置进行指针移动
cur = net
return pre #遍历结束后,pre节点所处的位置就是新链表的头结点
递归法:
class Solution(object):
def reverseList(self, head):#递归函数,传入head,传出反转后的链表
if head==None or head.next==None:#定义base case
return head
last = self.reverseList(head.next) #将head后的链表反转,返回新头结点last
head.next.next=head#将反转后的链表的尾结点指向head,head变成新尾结点
head.next=None#新尾结点指向None
return last#返回新头结点last
小结:
关于用递归来实现反转链表其实一开始看到是比较绕的,感觉不好理解,但正好可以用这一题来锻炼一下递归思维。还是关于递归的一些老话:我们并不需要跳入递归函数内部,光在函数体的第一层我们就可以实现逻辑的自洽,这样就够了。
反转链表是经典高频题了,建议两种方法都掌握一下,也都不难。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了