代码随想录算法训练营第四天 | 24. 两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题 02.07. 链表相交 142.环形链表II
24. 两两交换链表中的节点
题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
解题:
关键:
- cur的位置在要交换的两个节点的前面
- 具体如何交换的操作!!
- while种植条件:cur的下一个和下下个都不为空,不能写反不然会空指针异常,用and不是or
- 同样用虚拟头节点
点击查看代码
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummyhead=ListNode(next=head)
cur=dummyhead
while cur.next and cur.next.next:
tmp=cur.next
tmp1=cur.next.next.next
cur.next=cur.next.next
cur.next.next=tmp
tmp.next=tmp1
cur=cur.next.next
return dummyhead.next
19.删除链表的倒数第N个节点
题目:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
解题:
思路:链表不知道总长度,所以要用快慢双指针的移动来找到删除的节点。
关键:
- fast比slow快n+1步
- 终止条件:fast指向Null
点击查看代码
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummyhead=ListNode(next=head)
slow=dummyhead
fast=dummyhead
for i in range(n+1):
fast=fast.next
while fast:
slow=slow.next
fast=fast.next
slow.next=slow.next.next
return dummyhead.next
面试题 02.07. 链表相交
题目:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
解题:
思路:
- 求出两链表的长度;
- 确定哪个链表长,让cur1表示短链表,cur2表示长链表;
- 长cur2移动到和短cur1长度一样的位置处(末尾对齐),即同时移动(len2-len1)步;
- 用while同时向后移动cur1和cur2,如何指向同一个节点就返回节点。注意:判断句if cur1==cur2表示是否指向一个节点,而不是判断val值。
点击查看代码
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
lenA,lenB=0,0
curA=headA
while curA:
lenA+=1
curA=curA.next
curB=headB
while curB:
lenB+=1
curB=curB.next
cur1,cur2=headA,headB
if lenA>lenB: #cur1短,cur2长
cur1,cur2=cur2,cur1
len1,len2=lenB,lenA
else:
len1,len2=lenA,lenB
for i in range(len2-len1):
cur2=cur2.next
while cur1:
if cur1==cur2:
return cur1
else:
cur1=cur1.next
cur2=cur2.next
return None
142.环形链表II
题目:给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
解题:
思路:数学问题。快慢指针,fast每次移动2个节点,slow每次移动1个节点。
两个要点:
一、判断是否有环:fast和slow有相遇,说明有环。
二、找到环的入口:先走到fast和slow相遇点,然后让index1=fast和index2=head同时移动直到两者相遇,就是入口处。
相遇时,slow走的节点数:x+y,fast走的节点数:x+y+n(y+z)。构建等式可以知道x=z。
点击查看代码
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast=head
slow=head
while fast and fast.next:
fast=fast.next.next
slow=slow.next
if fast==slow:
index1=fast
index2=head
while index1!=index2:
index1=index1.next
index2=index2.next
return index1
return None
心得:
当在删除、交换等操作中,为了统一处理头结点和其他节点的规则时,需要使用虚拟头节点
画图理清思路很重要
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?