牛客网刷题-两个链表的第一个公共结点

问题描述

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

输入描述:
输入两个链表

输出描述:
输出第一个公共节点

示例

示例1

输入
4->1->8->4->5;5->0->8->4->5

输出
8->4->5

解决思路

分析

  1. 遍历链表1,使用额外的空间存储,遍历链表2,查找是否有相同的元素,相同为第一个公共节点。
    2.使用双指针法,但是双指针法的前提是遍历的链表的长度有规律,但是这两个链表第一个公共节点前的长度可能不一样,这里我们主要解决这个问题
    (1)假设链表1的长度是a,链表2的长度是b
    (2)使用双指针法的前提是两个链表的长度相等,那样每个链表一次next肯定会找到第一个公共节点
    (3)虽然a和b不想等,但是a+b=b+a,我们可以创造了两个长度相等的链表
    (4)有了a+b=b+a这个条件,我们就可以使用双指针法,当遍历到链表1的空节点,此时追加上链表2的长度;当遍历到链表2的空节点,此时追加上链表1,最终可以找到公共节点
    在这里插入图片描述
    在这里插入图片描述

方法

  1. hash法。
  2. 双指针法

代码实现

思路1:hash法

// 思路1
public class Solution {
    
      
	public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
    
    
        Set<ListNode> temp = new HashSet<>();
        while (pHead1 != null) {
    
    
            temp.add(pHead1);
            pHead1 = pHead1.next;
        }

        while (pHead2 != null) {
    
    
            if (temp.contains(pHead2)) {
    
    
                return pHead2;
            }
            pHead2 = pHead2.next;
        }

        return null;
    }
}

时间复杂度分析:
O(Max(M,N)):假设最后一个节点为公共节点,则需要遍历完链表1和链表2才能找到,所以时间复杂度为链表长度比较大的一项。

空间复杂度分析:
O(M):使用了额外Set集合存储链表1的节点。

思路2:双指针法

// 思路2
public class Solution {
    
      
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
    
    
        if (pHead1 == null || pHead2 == null) return null;
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        while (p1 != p2) {
    
    
            p1 = p1.next;
            p2 = p2.next;
            if (p1 != p2) {
    
    
                if (p1 == null) p1 = pHead2;
                if (p2 == null) p2 = pHead1;
            }
        }
        return p1;
    }
}

时间复杂度分析:
O(M+N):最终遍历的是两给链表加载一起的长度。

空间复杂度分析:
O(1):没有使用额外的空间。

小伙伴如果想测试的话,可以直接到牛客网这个链接做测试

两个链表的第一个公共结点-牛客网

猜你喜欢

转载自blog.csdn.net/qq_35398517/article/details/113767581
今日推荐