输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
这道题注意是公共节点,而非相同节点,如果是相同节点我们就直接用HashSet做了。当然这道题也是能用HashSet做的,只不过有一种不需要辅助空间,时间上依然是O(m+n)的做法。
因为是公共节点,意味着如果在第一个公共节点重合,那么后面的链表就合起来了,也就是公共时,两个链表走过的结点数应该是一致的。当length1==length2时,我们只需要判断是否节点公共,否则++即可。如果不相等,我们只需要给链表前面加上一段能让两个链表长度相等的无关链表段即可(因为公共段相等,所以当第一个公共节点到达时,肯定1和2都走过了相同的节点数,自然只可能是在无关段后面的1和2段,所以不需要考虑无关段的影响),那么无关段长度多少合适呢?显然length1+length2==length2+length1,我们直接把2和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 n1=pHead1,n2=pHead2; //当长度相等,双方均为null即走到尾部 //当长度不等,双方均为null即走到拼接后的尾部 while((n1!=null) || (n2!=null)){ if(n1==null){ n1=pHead2; } if(n2==null){ n2=pHead1; } //这道题不确定val是否重复,直接比较内存 if(n1==n2){ return n1; }else{ n1=n1.next; n2=n2.next; } } return n1; } }