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

今日你如约而至了吗?每天坚持,默默互相监督,希望秋招收到满意的offer。上题:

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

分析:找公共结点,我们首先要明白公共结点是什么意思?公共结点指从这个结点开始,两个链表的后面结点都相同,其实相当于Y,两个链表最后走在了一起。方法有暴力破解法,还有首尾相接法(很巧妙的);

方法一:暴力破解法
因为题目已经限定这两个链表一定存在结点,所以暴力破解法是可行的。
步骤:
    1、将链表1作为外循环,读取链表1的第一个数;
    2、将链表2赋给中间链表,作为内循环,读取中间链表的数;
    3、不断循环内循环,知道中间链表为null;
    4、将链表2重新赋值给中间链表,主要是链表自己不会回到头结点;
    5、将外循环向后移动一位,重复步骤3-5,直到结束。

代码:
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1==null||pHead2==null)return null;
        ListNode temp2=pHead2;      //中间链表,重新回到头结点。
        while(pHead1!=null){        //外循环
            while(temp2!=null){     //内循环
                if(temp2.val==pHead1.val){
                    return pHead1;
                }
                temp2=temp2.next;
            }
            temp2=pHead2;      //回到链表2的头结点;
            pHead1=pHead1.next;
        }
        return null;
    }
}
牛客运行通过
运行时间:22ms
运行内存:9660Kb
时间复杂度为O(m*n);

方法二:首尾相接法
举个例子:
pHead1=1-2-3-5-null
pHead2=4-3-5-null
p1=1-2-3-5-null-4-3-5-null
p2=4-3-5-null-1-2-3-5-null
这样就省去了求每个链表长度的麻烦。
代码:
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1==null||pHead2==null)return null;
        ListNode temp1=pHead1;
        ListNode temp2=pHead2;
        while(temp1!=temp2){
            temp1=temp1.next;
            temp2=temp2.next;
            if(temp1!=temp2){
                if(temp1==null)temp1=pHead2;  //首尾相接
                if(temp2==null)temp2=pHead1;
            }
        }
        return temp1;
    }
}
牛客运行通过
运行时间:23ms
运行内存:9592Kb
时间复杂度O(m+n)
第二种方法还是很巧妙的,但是会使用这种方法建立在对链表公共结点的正确理解上。
当然还有很多办法,例如先求出两个链表的长度,然后像快慢指针一样,长的链表先走,在一起走。这里不再代码表示出,可以去牛客上看题解。
欢迎各位互相交流哦~~

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值