剑指offer系列-面试题52. 两个链表的第一个公共节点两个链表的 (python)

1. 题目

输入两个链表,找出它们的第一个公共节点。

2. 解题思路

详情见 图解 双指针法,浪漫相遇
在这里插入图片描述

由于链表A和链表B长度不一定相同,而二者相交之后的链表都是相同的,因此这个题的难点在于A和B并不同步,所以造成无法比较两个链表中的节点是否相同。

2.1 渣渣思路

发现了上面的关键点之后,就写出了3.1的代码,思路如下:
1)分别遍历A和B,得到链表的长度差diff;
2)让长的链表先走diff步,然后两个链表再同时往下走,这样两者就是同步的了,可以进行比较了;
3)返回第一个相同的节点,即第一个交点。

2.2 最佳思路

画图更容易理解
两个指针 p 和 q,分别走A+B 和B+A,总长度是一样的,所以使得后面p和q是同步走的,就可以进行比较了。
1)p遍历链表A,q遍历链表B;
2)当p遍历到A的末尾后,再遍历B;
3)当q遍历到B的末尾后,再遍历A;
4)返回第一个交点。

3. 代码实现

3.1 渣渣解法

# 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:
        """
        因为链表的后部是一致的,所以A和B链表长度的差异,也就是在公共节点之前那部分的长度差异,只要两个指针能够同步前进,就能找到公共节点
        难点在于:若两个链表长度不一样的话,二者不会同时到达第一个公共节点,造成无法比对节点。
        """
        length_a = 0
        length_b = 0

        # 1.遍历链表A,得到链表A长度
        temp = headA
        while temp:
            length_a += 1
            temp = temp.next

        # 2.遍历链表B,得到链表B长度
        temp = headB
        while temp:
            length_b += 1
            temp = temp.next

        # 3. 消去两个链表的差值,使得同步检查两个链表
        difference = length_a - length_b

        if length_a > length_b: # 让headA先走difference步,否则headB先走difference步,使得二者同步
            while difference:
                headA = headA.next
                difference -= 1
        else:
            difference = -1 * difference
            while difference:
                headB = headB.next
                difference -= 1

        while headA:
            if headA == headB:
                return headA
            headA = headA.next
            headB = headB.next

        return

3.2 最优解法

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        node1, node2 = headA, headB
        
        while node1 != node2:
            node1 = node1.next if node1 else headB
            node2 = node2.next if node2 else headA

        return node1

作者:z1m
链接:https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/solution/shuang-zhi-zhen-fa-lang-man-xiang-yu-by-ml-zimingm/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4. 总结

链表中的操作,大致为一下几种:

  1. 双指针(同速走,倍速走,相差k步走);
  2. 创建伪节点;
  3. 改变链接,改变元素值;
  4. 消除长度差。

5. 参考文献

[1] 剑指offer丛书
[2] 剑指Offer——名企面试官精讲典型编程题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值