题目描述
输入两个链表,找出它们的第一个公共结点。
思路:这题刚开始跟上题一样,直接暴力嵌套,但是太浪费时间了,因为那样时间将为O(n^2)。所以小套路又来了。
首先我们发现如果两个链表有公共节点,方便理解这里到了两张图,两个链表等长(图a)或者不等长(图b)。
图a
图b
等长的情况比较好处理,起始处不等长的情况我们需要来点小歪招了,就是两个数组串起来,先结束的数组结尾处拼接较长数组,较长数组结尾拼接短数组。
如数组int[] a =1234 ,int [] b = 534 。拼接完两数组等长,这时记录数字a、b的两个指针p1、p2从头遍历到结尾。有重叠即公共节点则为p1,没有时p1为null。
原理其实很简单:两个数组拼接后,两个新数组长度一致,因为如果有公共节点,那么肯定是结尾处有大于等于1个相同数字。现在两个数组长度相等的条件已经具备了,这时我们得到相等的首个数字即可。如果没有相等数字,那么则诶呦共同节点。
/*
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 p1 = pHead1,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;
}
}
空间复杂度:O(1);
时间复杂度:O(m+n);