一、题目描述
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的),如下图,找第一个公共结点,这里就是c1。
二、分析
我们首先可以想到的方法就是暴力破解,即让用两个指针分别指向两链表的表头,然后让链表2中指针往后移动,看是否有与链表1(a1-c3)中指针指向的结点相同的结点。没有则链表1中指针往后移动一位,链表2指针由回到表头,再次往后移动。
2.1 方法一
暴力破解,假设链表1长度为m,链表2长度为n,时间复杂度为O(mn)
代码如下:
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode temp1 = pHead1;
ListNode temp2 = pHead2;
while(temp1 != null){
while(temp2 !=null){
if(temp1 == temp2){
return temp1; //找到公共结点
}
temp2 = temp2.next;
}
temp2 = pHead2;
temp1 = temp1.next;
}
return null; //未找到公共结点
}
}
2.2 方法二
第二种方法就是利用链表结点的数量关系,我们再把开始的图拿出来,链表1(a1-c3)有5个结点,链表2(b1-c3)有6个结点,两个链表的结点虽然不一样多,但是如果让链表1中指针temp1遍历完后再遍历链表2,链表2中指针temp2遍历完后再遍历链表1,这样5+6 = 6+5,不就一样了嘛,虽然链表1中结点少,但是两个链表总数相等,即后面一定会重合,指向同一结点。temp1==null表示走到最后了,时间复杂度O(m+n)。
代码如下:
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode temp1 = pHead1;
ListNode temp2 = pHead2;
while(temp1 != temp2){
temp1 = (temp1 == null) ? pHead2 : temp1.next;
temp2 = (temp2 == null) ? pHead1 : temp2.next;
}
return temp1;
}
}