剑指offer | 面试题52:两个链表的第一个公共节点

转载本文章请标明作者和出处
本文出自《Darwin的程序空间》
本文题目和部分解题思路来源自《剑指offer》第二版

在这里插入图片描述

开始行动,你已经成功一半了,献给正在奋斗的我们

题目

输入两个链表,找出它们的第一个公共节点;
如下,第一个公共节点为节点6;
在这里插入图片描述

解题分析

首先以图示例,图中有两个链表相交与节点6,问公共节点是什么?
这道题第一个我的想法是使用哈希表(HashMap)来解决,我们可以首先找一条链表遍历一下,把这个链表的所有节点存起来,那么遍历第二条链表的时候,第一个在哈希表中已经存在的节点,即是第一个公共节点,也为所求;这个解法是一般人都能够想得到的,并且时间复杂度也是O(m+n),基本也是最优,就是也使用了O(m+n)的空间,所以一般不推荐这种做法;

还有一种是用栈,就是将两个链表都压入栈中,然后依次pop节点,直到最后一个相同的节点,就是第一个公共节点,这种做法利用了栈先进后出的特性,让一样的先出来,这样最后一个不一样的就是第一个公共节点;这样同样会使用O(m+n)的空间,并且是线上还不如方法一来的直观,所以笔者也不做推荐;


首先,我们确认一下,之所以,两个链表遍历的过程中不能同时到达,节点6,是因为距离节点6的距离不一样远,第一条链表需要走三步,第二条链表需要走两步,而走完这几步之后,后面的公共部分,都是一样的;那我们怎么能在遍历的时候让其同时到达第一个入口呢?

其实很简单,第一次遍历的时候是不是链表一因为长多跑了一个节点,好,等链表一遍历完了,立马去遍历链表二,链表二也别高兴,链表二遍历完了立马去遍历链表了,这样,第一轮遍历,多遍历的一个节点,会在第一个公共节点处还回来,所以,第二次遍历一定会在第一个公共节点处相遇;

表现在代码上就是第一次遍历当下一个元素为空(前面没有路了),立刻把指针指向另一个链表的头节点即可;如果第二次遍历还没有相交点,只能说明一个情况,压根两个链表没相交;

代码(JAVA实现)

ps:这里笔者使用的jdk为1.8版本

public class FindFirstCommonNode {

    public static void main(String[] args) {
        ListNode l1 = new ListNode(1);
        ListNode l2 = new ListNode(2);
        ListNode l3 = new ListNode(3);
        ListNode l4 = new ListNode(4);
        ListNode l5 = new ListNode(5);
        l1.next = l2;
        l2.next = l4;
        l4.next = l5;
        System.out.println(findFirstCommonNode(l1,l3).val);

    }

    public static ListNode findFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if (Objects.isNull(pHead1) || Objects.isNull(pHead2)) {
            return null;
        }
        ListNode point1 = pHead1;
        ListNode point2 = pHead2;
        int count = 0;
        while (point1 != point2) {
            if (count > 2) {
                // 此时证明根本没有交点
                return null;
            }
            point1 = point1.next;
            point2 = point2.next;
            if (Objects.isNull(point1)) {
                point1 = pHead2;
                count++;
            }
            if (Objects.isNull(point2)) {
                point2 = pHead1;
                count++;
            }
        }
        return point1;
    }
}

代码分析

count第一次加一是短的链表遍历到了终点,第二次是长的链表遍历到了终点,按理说不应该有第三次,如果有的话,就说明压根没有交点;


喜欢的朋友可以加我的个人微信,我们一起进步
发布了156 篇原创文章 · 获赞 19 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/qq_36929361/article/details/104394680
今日推荐