算法通关村第一关-链表经典问题之两个链表第一个公共子节点笔记

寻找两个链表第一个公共节点

这是一道经典的链表问题,剑指offer52 先看一下题目:输入两个链表,找出它们的第一个公共节点。例如下面的两个链表:在这里插入图片描述
两个链表的头结点都是已知的,相交之后成为一个单链表,但是相交的位置未知,并且相交之前的结点数也是未知的,请设计算法找到两个链表的合并点。
我们用两种方法来解决这道题:1.集合 2.字符串拼接

集合法

首先将第一个链表存放到集合中,然后使用集合的contains()方法遍历第二个链表来判断是否有相同元素,主要代码如下:

public static Node findFirstCommonNodeBySet(Node head1,Node head2){
        Set<Node> set = new HashSet<>();
        while(head1!=null){
            set.add(head1);
            head1 = head1.next;
        }

         while(head2!=null){
             if(set.contains(head2)){
                 return head2;
             }
             head2 = head2.next;
         }

拼接字符串法

我们假定A和B有相交的位置,以交点为中心,可以将两个链表分别分为left_a和right_a,left_b和right_b这样四个部分,并且right_a和right_b是一样的,这时候我们拼接AB和BA就是这样的结构:
在这里插入图片描述
right_a和right_b是一样的,那这时候分别遍历AB和BA就能从某个位置开始找到相交的点,使用这种方法的关键点在于两条链表相交后是单链表,如果不是则不能使用该方法,主要代码如下:

public static Node findFirstCommonNodeByCombine(Node pHead1,Node pHead2) {
        if(pHead1 == null && pHead2 == null){
            return null;
        }
        Node p1 = pHead1;
        Node 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;
    }

注意点:
1.说是拼接但实际上只是在遍历完第一个链表后将第二个链表接在后面,并没有创建新的链表,所以要创建新的变量防止改动头指针的位置。
2.对if()判断条件的理解,当list1为123,list2为45时,如果没有这个判断条件则会进入死循环,那这个条件是如何结束死循环的呢?因为”拼接"完后两个链表的总长度是一样的,当都遍历到最后一个元素时,此时p1.next和p2.next同时都为空,满足条件,退出循环。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值