2024/12/1 【链表】 LeetCode 面试题 02.07. 链表相交
面试题 02.07. 链表相交 - 力扣(LeetCode)
文心一言:
首先,getIntersectionNode
方法中调用了 self.getIntersectionNode2(headA, headB)
等,但这些调用没有使用它们的返回值。getIntersectionNode2
方法返回相交节点,但您在 getIntersectionNode
方法中没有处理这个返回值。
我的理解:在被调用函数getIntersectionNode2(headA, headB)中return了结果,在getIntersectionNode要return这个调用。
self.getIntersectionNode2(headA, headB)语句仅仅调用了这个函数,应该用 return self.getIntersectionNode2语句返回
结果。
另外,getIntersectionNode
方法的签名表明它应该返回一个 ListNode
对象,但在长度相等且没有相交节点的情况下,它实际上返回了 None
(隐式地,因为没有返回语句)。这是正确的行为,但最好明确这一点。
代码随想录给出的一个解法:
不能直白理解,需要多想想
(版本四)等比例法 # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: # 处理边缘情况 if not headA or not headB: return None # 在每个链表的头部初始化两个指针 pointerA = headA pointerB = headB # 遍历两个链表直到指针相交 while pointerA != pointerB: # 将指针向前移动一个节点 pointerA = pointerA.next if pointerA else headB pointerB = pointerB.next if pointerB else headA # 如果相交,指针将位于交点节点,如果没有交点,值为None return pointerA
为什么这种方法有效?
- 假设链表
A
的长度为a + c
,其中a
是从链表头部到相交点的长度,c
是从相交点到链表末尾的长度(如果链表不相交,我们可以想象c
为0,即相交点在链表A
的末尾之后)。 - 假设链表
B
的长度为b + c
,同理定义b
和c
。 - 当
pointerA
遍历完链表A
的a
部分后,它会被重置为headB
,并继续遍历链表B
的b
部分。此时,pointerB
已经遍历了链表B
的b
部分。 - 当
pointerB
遍历完链表B
的b
部分后,它会被重置为headA
,并继续遍历链表A
的a
部分。此时,pointerA
已经遍历了链表B
的b
部分,并正在遍历c
部分。 - 因此,当两个指针都遍历了
a + b
的长度后,它们都会到达链表A
或B
的c
部分,并在相交点相遇(如果存在)。如果链表不相交,则它们会同时到达链表的末尾。
直观理解
想象两个跑步者从两个不同的起点(链表A
和B
的头节点)开始跑步。他们各自沿着自己的路径跑,直到到达路径的末尾。然后,他们分别跳转到对方的起点,并继续跑。由于他们跑的总距离是相同的(都是a + b + c,
),如果他们最终能在某个点相遇,那么这个点必然是相交点。如果他们不能相遇,那么说明两个链表不相交。
希望这次解释能帮助你更好地理解链表相交问题的双指针解决方案。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】