两个链表的第一个公共节点

一、需求

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

       

  • 在节点 c1 开始相交。

二、双指针(暴力)

2.1  思路分析

  1. 采用双重循环,使用两个指针p、q分别指向链表A和链表B,外循环遍历链表A,内循环遍历链表B,每次判断当前链表A的节点是否就是当前链表B的节点,如果是就返回该节点,否则就一直遍历,直到链表A遍历结束;
  2. 如果不存在公共结点,则返回null;
  3. 因为本题要求时间复杂度限制在O(1),故该方法在运行时会出现超时;

2.2  代码实现

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode p = headA;
        while(p != null) {
            ListNode q = headB;
            while(q != null) {
                if(p == q) return p;
                q = q.next;
            }
            p = p.next;
        }
        return null;
    }
}

2.3  复杂度分析

  • 时间复杂度为O(n^2),因为采用了双重循环,计算次数为n^2;
  • 空间复杂度为O(1),变量p,q占用常数大小的额外空间;

三、双指针法(优化)

3.1  思路分析

  1. 假设链表A、B存在公共节点,链表A头节点距离公共节点为L1步,即[A头节点,公共节点),链表B头节点距离公共节点为L2步,即[B头节点,公共节点),两个链表的公共部分长度为C;
  2. 那么根据L1+C+L2 = L2+C+L1的原理,设指针p,q指向链表A,B,p,q同时移动,当p走过L1+C+L2后,q走过L2+C+L1后,它们会在公共结点相遇;

3.2  代码实现

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode p = headA;
        ListNode q = headB;
        while(p != q) {
            //这里让双指针同时移动,避免了循环
            p = p != null ? p.next : headB;
            q = q != null ? q.next : headA;
        }
        return p;
    }
}

3.3  复杂度分析

  • 时间复杂度为O(n);
  • 空间复杂度为O(1);

四、学习地址

作者:腐烂的橘子

链接: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/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值