数据结构与算法 —— 链表linked list(05)
反转一个单链表。
进阶:
链表可以迭代或递归地反转。你能否两个都实现一遍?
示例 :
给定这个链表:1->2->3->4->5
返回结果: 5->4->3->2->1
解题思路:
1. 迭代版本:
循环列表,定义两个指针,一个指针是已经迭代完的链表的最后一个节点称为last_node,一个指针是已经迭代完的节点的第一个节点称为next_node。
刚开始的时候last_node 和next_node都指向链表head,循环last_node的next节点定义为cur,把last_node的next指向cur的next指针,把cur的next指向next_node节点。
next_node赋值为当前的cur节点。
最后返回next_node即可。
图如下
1 ->2 ->3 ->4 ->5
|
next_node
last_node
循环完1之后
2 ->1 ->3 ->4 ->5
| |
| last_node
next_node
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # Definition for singly-linked list. class ListNode( object ): def __init__( self , x): self .val = x self . next = None class Solution( object ): def reverseList( self , head): """ :type head: ListNode :rtype: ListNode """ if not head: return None last_node = head next_node = head while (last_node. next ): cur = last_node. next cur_next = cur. next cur. next = next_node last_node. next = cur_next next_node = cur return next_node |
2. 递归版本
递归:递归,就是在运行的过程中调用自己。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None class Solution( object ): def reverseList( self , head): """ :type head: ListNode :rtype: ListNode """ if head is None or head. next is None : return head pre_node = self .reverseList(head. next ) head. next . next = head head. next = None return pre_node |
反转链表 II
反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
解题思路:
可以先找到翻转的开始位置,这里是2,然后根据这个位置将链表断开:1->null, 2->3->4->5->null,这就形成了两个链表。
然后,将第二个链表依次取头结点,放在1的后面:
1. 1->2->null, 3->4->5->null
2. 1->3->2->null, 4->5->null
。。。
这样的循环进行几次呢,循环3次,也就是n - m + 1次
之后再将现在的两个链表合并即可。代码就可以得到了
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None class Solution( object ): def reverseBetween( self , head, m, n): """ :type head: ListNode :type m: int :type n: int :rtype: ListNode """ dummy = ListNode( - 1 ) dummy. next = head pre = dummy num = 1 # 找到要翻转部分的开始 while num ! = m: pre = pre. next num + = 1 # gap为循环的次数 gap = n - m + 1 # 第二部分 next_part = pre. next # 设置第一部分的尾节点,目的在于最后的合并 tail = next_part pre. next = None while gap ! = 0 : cur = next_part next_part = next_part. next temp = pre. next pre. next = cur cur. next = temp gap - = 1 # 两部分合并 tail. next = next_part return dummy. next |
coding交流群:226704167,,郑州程序员群:59236263愿和各位一起进步!
微信公众号:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!