[每日一道小算法(五十二)] [链表] 两个链表的第一个公共结点(剑指offer题)

前言:
我这脑子。唉,以前做过这道题的,还是想了好久。。。。。

题目描述

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

解题思路

这道题刚开始一看,我们就可以想到暴力解法。我们先取出一个链表的结点,然后再另一个另一个链表进行遍历。这样循环求解。这样方法是不好的,时间复杂度达到了O(m*n)。所以不建议使用这种方法。
之后,我在好好理解一下这个题意。这是一个单链表,也就是只有一个指针指向下一结点。所以一旦链表有相同的结点,那么就说明这两个链表构成Y型结构的链表。所以这两个链表公共点之后的所有结点都是相同,所以我们可以从后向前遍历,直到找到不同结点的前一个结点,则就是公共结点。这里就需要用到两个辅助栈来实现。这里只提供方法没有具体实现。本例提供代码是方法三。
方法三就是我们可以先遍历一遍两个链表,然后算出两个链表的长度,然后计算出长度差,让长链表先走差值,这样这两个链表的就处于一个位置了,这样这开始遍历比较。这个实现也比较简单。这里有一个比较简单的代码实现。
创建两个指针p1和p2,分别指向两个链表的头结点,然后依次往后遍历。如果某个指针到达末尾,则将该指针指向另一个链表的头结点;如果两个指针所指的节点相同,则循环结束,返回当前指针指向的节点。比如两个链表分别为:1->3->4->5->6和2->7->8->9->5->6。短链表的指针p1会先到达尾部,然后重新指向长链表头部,当长链表的指针p2到达尾部时,重新指向短链表头部,此时p1在长链表中已经多走了k步(k为两个链表的长度差值),p1和p2位于同一起跑线,往后遍历找到相同节点即可。其实该方法主要就是用链表循环的方式替代了长链表指针先走k步这一步骤。

代码样例

package com.asong.leetcode.FindFirstCommonNode;

/**
 * 两个链表的第一个公共结点
 * 输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
 */
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 = pHead1;
                if(p2==null) p2 = pHead2;
            }
        }
        return p1;
    }
}

发布了159 篇原创文章 · 获赞 37 · 访问量 4488

猜你喜欢

转载自blog.csdn.net/qq_39397165/article/details/104398362