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,同理定义bc
  • pointerA遍历完链表Aa部分后,它会被重置为headB,并继续遍历链表Bb部分。此时,pointerB已经遍历了链表Bb部分。
  • pointerB遍历完链表Bb部分后,它会被重置为headA,并继续遍历链表Aa部分。此时,pointerA已经遍历了链表Bb部分,并正在遍历c部分。
  • 因此,当两个指针都遍历了a + b的长度后,它们都会到达链表ABc部分,并在相交点相遇(如果存在)。如果链表不相交,则它们会同时到达链表的末尾。

直观理解

想象两个跑步者从两个不同的起点(链表AB的头节点)开始跑步。他们各自沿着自己的路径跑,直到到达路径的末尾。然后,他们分别跳转到对方的起点,并继续跑。由于他们跑的总距离是相同的(都是a + b + c,),如果他们最终能在某个点相遇,那么这个点必然是相交点。如果他们不能相遇,那么说明两个链表不相交。

希望这次解释能帮助你更好地理解链表相交问题的双指针解决方案。

posted @   axuu  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示