題目如下:
輸入兩個鏈表,找出它們的第一個公共結點。(注意因爲傳入數據是鏈表,所以錯誤測試數據的提示是用其他方式顯示的,保證傳入數
據是正確的)
因爲鏈表都是單向鏈表,一旦兩個鏈表有公共的節點,則從該節後往後的節點都是相同的。因爲單向鏈表中不會存在一個結點有兩個不同的節點。整個圖形,類似於一種Y形結構。
根據以前圖形,從尾結點到最後一個相同的節點都是公用的部分,如果我們能夠從尾部向首部遍歷,則只需要找最後一個相同的節點即可,但是這是單向鏈表,只可以從前往後遍歷。
上面只是爲了想要兩個節點到達公共節點的時機一致,那麼能否人工控制遍歷的節奏呢?
類似於小明小紅,在兩個跑道上跑步,尋找兩個第一次相遇的地點,並且兩人跑步速度完全一致,如果小明離終點的距離比小紅遠,同時跑無論怎麼樣都難以相遇。可以讓小明先跑一小段,然後再同時跑
該題的思路與上述類似。因此關鍵點有以下幾點:
- 需要提前知道兩個鏈表的長度。
- 同時判斷兩個節點是否相等。
代碼如下:
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode result = null;
if(pHead1 == null || pHead2 == null){
return null;
}
int m = 0;
int n = 0;
ListNode current1 = pHead1;
// 求解鏈表1的長度
while(current1!=null){
m++;
current1 = current1.next;
}
ListNode current2 = pHead2;
// 求解鏈表2的長度
while(current2!=null){
n++;
current2 = current2.next;
}
// 讓鏈表長的一方先遍歷
if(m>n){
for(int i = 0;i < m-n;i++){
pHead1 = pHead1.next;
}
}else{
for(int i = 0; i < n-m; i++){
pHead2 = pHead2.next;
}
}
// 最後比較是否真的會相遇
while(pHead1 != null && pHead2!= null){
if(pHead1 == pHead2){
result = pHead1;
break;
}
pHead1 = pHead1.next;
pHead2 = pHead2.next;
}
return result;
}
}
總結
此題在於尋找問題的關鍵,一旦相遇之後,再也不會分開。