今日你如约而至了吗?每天坚持,默默互相监督,希望秋招收到满意的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)
第二种方法还是很巧妙的,但是会使用这种方法建立在对链表公共结点的正确理解上。
当然还有很多办法,例如先求出两个链表的长度,然后像快慢指针一样,长的链表先走,在一起走。这里不再代码表示出,可以去牛客上看题解。
欢迎各位互相交流哦~~