描述
輸入兩個無環(huán)的單鏈表非凌,找出它們的第一個公共結(jié)點。(注意因為傳入數(shù)據(jù)是鏈表荆针,所以錯誤測試數(shù)據(jù)的提示是用其他方式顯示的敞嗡,保證傳入數(shù)據(jù)是正確的)
題解
題目抽象:給定兩個單鏈表A,B
航背,假設(shè)一定含有公共結(jié)點喉悴,返回第一個公共結(jié)點的指針。
方法:雙指針法
假如例子如下:
圖片說明
顯然第一個公共結(jié)點為8
玖媚,但是鏈表A
頭結(jié)點到8
的長度為2
粥惧,鏈表B
頭結(jié)點到8
的長度為3
,顯然不好辦最盅?
如果我們能夠制造一種理想情況突雪,如下:
圖片說明
這里先假設(shè)鏈表A
頭結(jié)點與結(jié)點8
的長度 與 鏈表B
頭結(jié)點與結(jié)點8
的長度相等,那么就可以用雙指針涡贱。
- 初始化:指針
ta
指向鏈表A
頭結(jié)點咏删,指針tb
指向鏈表B
頭結(jié)點 - 如果
ta == tb
, 說明找到了第一個公共的頭結(jié)點问词,直接返回即可督函。 - 否則,
ta != tb
激挪,則++ta辰狡,++tb
所以現(xiàn)在的問題就變成,如何讓本來長度不相等的變?yōu)橄嗟鹊模?br>
假設(shè)鏈表A
長度為a
垄分, 鏈表B
的長度為b
宛篇,此時a != b
但是,a+b == b+a
因此薄湿,可以讓a+b作為鏈表A的新長度叫倍,b+a作為鏈表B的新長度偷卧。
如圖:
圖片說明
這樣,長度就一致了吆倦,可以用上述的雙指針解法了听诸。
題解
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
ListNode p1 = pHead1;
ListNode 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;
}