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

Posted 大朱123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两个链表的第一个公共节点相关的知识,希望对你有一定的参考价值。

1:题目描述

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

如下面的两个链表:

 

 

在节点 c1 开始相交。尽量满足时间复杂度为O(n)和空间复杂度为O(1)即可。

2:题目分析

2.1:利用HashSet

  将第一个链表所有节点保存起来,然后遍历第二链表,找到第一个已经在Set里的节点即可。

2.2:双指针遍历

  假设HeadA长度为 = La + C,HeadB长度为 = Lb + C,其中C为公共长度,La和Lb为各自不共有的长度。当前仅当两个列表的指针走了La+Lb+C步的时候(其中两个指针当走完本链表时,开始从头走另外一个链表),两个指针走的步数相等,并且会正好走到第一个公用节点。详细参看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/同学的做法

3:代码示例

3.1:利用HashSet

package JianZhiOffer52;

import java.util.HashSet;

/**
 * @author :dazhu
 * @date :Created in 2020/4/4 9:11
 * @description:
 * @modified By:
 * @version: $
 */
public class Main {
    public static void main(String[]args){
        ListNode n0 = new ListNode(0);
        ListNode n1 = new ListNode(1);
        ListNode n2 = new ListNode(2);
        ListNode n3 = new ListNode(3);
        ListNode n4 = new ListNode(4);
        ListNode n5 = new ListNode(5);

        n0.next = n1;
        n1.next = n2;
        n2.next = n3;
        n3.next = n4;
        n4.next = n5;

        ListNode n00 = new ListNode(0);
        ListNode n11 = new ListNode(11);
        ListNode n22 = new ListNode(22);
        n00.next = n11;
        n11.next = n22;
        n22.next = n3;

        Solution solution = new Solution();
        solution.getIntersectionNode(n0,n00);

    }
}


class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        HashSet<ListNode> hs = new HashSet<>();
        ListNode curNode = headA;
        //遍历A,加入hs
        while(true){
            if(curNode == null){
                break;
            }
            hs.add(curNode);
            curNode = curNode.next;
        }
        //遍历B,判断是不是已经出现过的
        curNode = headB;
        while(true){
            if(curNode == null){
                break;
            }
            //如果是,直接return
            if(hs.contains(curNode)){
                return curNode;
            }
            curNode = curNode.next;
        }
        return null;
    }
}

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
        next = null;
    }
}

3.2:双指针遍历

class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null||headB == null){
            return null;
        }
        ListNode curNode1 = headA;
        ListNode curNode2 = headB;
        int timesA = 0;
        int timesB = 0;
        while(true){
            //第一次遍历结束后,从零外一个链表开始再遍历
            if(curNode1 == null){
                curNode1 = headB;
                if(timesA == 1){
                    return null;
                }
                timesA++;
            }
            //第一次遍历结束后,从零外一个链表开始再遍历
            if(curNode2 == null){
                curNode2 = headA;
                if(timesB == 1){
                    return null;
                }
                timesB++;
            }
            //找到了,直接return
            if(curNode1 == curNode2){
                return curNode1;
            }

            curNode1 = curNode1.next;
            curNode2 = curNode2.next;

        }
    }
}

 

以上是关于两个链表的第一个公共节点的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer两个链表的第一个公共结点

leetcode-两个链表的第一个公共节点-47

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

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

剑指offer:求两个链表的第一个公共节点

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