题目:输入两个链表,找出它们的第一个公共结点。
思路一:
1、先求出两个链表的长度差gap,让比较长的链表先向前遍历gap个节点,然后两个链表同时向前遍历,直到遇到相同的节点为止。时间复杂度:O(m+n);m和n分别为两个链表的长度。
/**
* 解法一:求得两个链表的长度差d,让较长的链表先走d步,然后两个链表再一起遍历,时间复杂度O(m+n)
* @param pHead1
* @param pHead2
* @return
*/
public static ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1==null||pHead2==null){
return null;
}
ListNode p1=pHead1;
ListNode p2=pHead2;
int p1Length=0;
int p2Length=0;
while (p1!=null){
p1Length++;
p1=p1.next;
}
while (p2!=null){
p2Length++;
p2=p2.next;
}
if(p1Length>p2Length){
p1=walkStep(pHead1,p1Length-p2Length);
p2=pHead2;
}else{
p1=pHead1;
p2=walkStep(pHead2,p2Length-p1Length);
}
while (p1!=null){
if(p1==p2) return p1;
p1=p1.next;
p2=p2.next;
}
return null;
}
public static ListNode walkStep(ListNode pHead, int step){
while(step>0){
pHead = pHead.next;
step--;
}
return pHead;
}
public static void main(String [] args){
ListNode b1 = new ListNode(1);
ListNode b2 = new ListNode(2);
ListNode b3 = new ListNode(3);
ListNode b4 = new ListNode(4);
ListNode b5 = new ListNode(5);
ListNode b6 = new ListNode(6);
ListNode b7 = new ListNode(7);
b1.next = b2;
b2.next = b3;
b3.next = b6;
b6.next = b7;
b4.next = b5;
b5.next = b6;
ListNode a=FindFirstCommonNode(b1,b4);
System.out.println(a);
}
思路二:如下图;将链表分为两部分,则两个链表的长度分别为a+c,b+c;得到a+c+b=b+c+a(即链表A遍历结束后从链表B开始遍历,链表B遍历结束后从链表A开始遍历,当两个链表的指针相遇时,就是第一个公共结点)
代码:
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode l1 = pHead1, l2 = pHead2;
while (l1 != l2) {
l1 = (l1 == null) ? pHead2 : l1.next;
l2 = (l2 == null) ? pHead1 : l2.next;
}
return l1;
}