劍指offer—兩個鏈表的第一個公共結點

題目如下:

輸入兩個鏈表,找出它們的第一個公共結點。(注意因爲傳入數據是鏈表,所以錯誤測試數據的提示是用其他方式顯示的,保證傳入數
據是正確的)

因爲鏈表都是單向鏈表,一旦兩個鏈表有公共的節點,則從該節後往後的節點都是相同的。因爲單向鏈表中不會存在一個結點有兩個不同的節點。整個圖形,類似於一種Y形結構。

在這裏插入圖片描述

根據以前圖形,從尾結點到最後一個相同的節點都是公用的部分,如果我們能夠從尾部向首部遍歷,則只需要找最後一個相同的節點即可,但是這是單向鏈表,只可以從前往後遍歷。
上面只是爲了想要兩個節點到達公共節點的時機一致,那麼能否人工控制遍歷的節奏呢?

類似於小明小紅,在兩個跑道上跑步,尋找兩個第一次相遇的地點,並且兩人跑步速度完全一致,如果小明離終點的距離比小紅遠,同時跑無論怎麼樣都難以相遇。可以讓小明先跑一小段,然後再同時跑

該題的思路與上述類似。因此關鍵點有以下幾點:

  1. 需要提前知道兩個鏈表的長度。
  2. 同時判斷兩個節點是否相等。

代碼如下:

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;
    }
}

總結

此題在於尋找問題的關鍵,一旦相遇之後,再也不會分開。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章