【链表】两个链表的第一个公共结点

题目描述

输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)


解法

这题首先需要理解两个链表的公共节点的意思,如果两个链表有公共节点,说明两个链表都指向同一个节点,因为引用数据类型在堆中存储的是地址,那么相遇后就合并成一条链了,如下图所示
在这里插入图片描述

计算长度法

一个最直观的解法是分别计算链表A和B的长度,然后将长的链表和短的链表对齐,齐头并进,找到地址相同的公共节点

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
    
    
    // 计算两个链表的长度
    int len1 = 0, len2 = 0;
    ListNode tmp1 = pHead1, tmp2 = pHead2;
    while (tmp1 != null) {
    
    
        tmp1 = tmp1.next;
        len1++;
    }
    while (tmp2 != null) {
    
    
        tmp2 = tmp2.next;
        len2++;
    }

    // 对齐,让长的链表头先走一段距离,和短的链表对齐
    if (len1 > len2)
        for (int i = 0; i < (len1 - len2); i++)
            pHead1 = pHead1.next;
    if (len2 > len1)
        for (int i = 0; i < (len2 - len1); i++)
            pHead2 = pHead2.next;
    // 齐头并进,找出公共节点
    while (pHead1 != null && pHead2 != null) {
    
    
        if (pHead1 == pHead2)
            return pHead1;
        pHead1 = pHead1.next;
        pHead2 = pHead2.next;
    }
    return null;
}
优化解法

这个解法相当于把两个链表连在一起了,例如对于两个链表

A: 0-1-2-3-4-5-null
B: a-b-4-5-null

下面的代码相当于把两个链表拼在一起,即0-1-2-3-4-5-null--a-b-4-5-nulla-b-4-5-null--0-1-2-3-4-5-null,拼接后两个链表长度一样,一起齐头并进找到公共节点

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
    
    
	ListNode tmp1 = pHead1, tmp2 = pHead2;
	while (tmp1 != tmp2) {
    
    
	    if (tmp1 != null)
	        tmp1 = tmp1.next;
	    if (tmp2 != null)
	        tmp2 = tmp2.next;
	    if (tmp1 != tmp2) {
    
    
	        if (tmp1 == null)
	            tmp1 = pHead2;
	        if (tmp2 == null)
	            tmp2 = pHead1;
	    }
	}
	return pHead1;
}

猜你喜欢

转载自blog.csdn.net/weixin_43486780/article/details/113481466