劍指offer 36:兩個鏈表的第一個公共節點--- Java實現

劍指offer每日一題算法題(java解法)

方便日後複習,從今天開始。

算法之行始於足下

[編程題]兩個鏈表的第一個公共節點-- Java實現

------------------------------------------------------------------------------------------------------
題目描述
輸入兩個鏈表,找出它們的第一個公共結點。

前提:
理解什麼是公共節點,公共節點的意思就是當前節點值相等,且後面的子鏈表值和長度一一對應相等
在這裏插入圖片描述

解題思路:
方法一

最直觀就是暴力法,在第一鏈表上順序遍歷每個節點,每遍歷到一個節點,就在第二個鏈表上順序遍歷每個節點。如果在第二個鏈表上有一個節點和第一個鏈表上的節點一樣,則說明兩個鏈表在這個節點上重合,但是這種方法的複雜度爲O(m∗nm * nm∗n)(第一個鏈表長度爲m,第二個鏈表的長度爲n)
方法二

如果兩個鏈表存在公共節點,那麼公共節點出現在兩個鏈表的尾部。如果我們從兩個鏈表的尾部開始往前比較,那麼最後一個相同的節點就是我們要找的節點。但是這兩個鏈表是單向的,要實現尾節點最先比較,我們可以藉助兩個輔助棧。分別將兩個鏈表的節點放入兩個棧中,這樣棧頂就是兩個鏈表的尾節點,比較兩個棧頂節點是否相同,如果相同,將棧頂彈出比較下一個棧頂,直到找到最後一個相同的棧頂。時間複雜度O(m + n)。

/*
public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}*/
import java.util.Stack;
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1==null||pHead2==null) return null;
        Stack<ListNode> pStack1=new Stack<ListNode>();
        Stack<ListNode> pStack2=new Stack<ListNode>();
        while(pHead1!=null){
            pStack1.push(pHead1);
            pHead1=pHead1.next;
        }
        while(pHead2!=null){
            pStack2.push(pHead2);
            pHead2=pHead2.next;
        }
        ListNode tmp=null;
        while(!pStack1.isEmpty()&&!pStack2.isEmpty()){
            ListNode pH1=pStack1.pop();
            ListNode pH2=pStack2.pop();
            if(pH1.val==pH2.val){
                tmp=pH1;
            }else{
                break;
            }
        }
        return tmp;
    }
}

方法三

先獲得兩個鏈表的長度,然後在較長的鏈表上先走若干步(兩鏈表長度之差),接着同時在兩個鏈表上遍歷,找到的第一個相同的節點就是他們的第一個公共節點。時間複雜度O(m + n)。

public ListNode FindFirstCommonNode_2(ListNode pHead1, ListNode pHead2) {
     if(pHead1 == null || pHead2 == null) {
      return null;
     } 
     int pHead1Length = getListLength(pHead1);
     int pHead2Length = getListLength(pHead2);  
     int gap = pHead1Length - pHead2Length;
     ListNode tempList1 = pHead1;
     ListNode tempList2 = pHead2;   
     if(pHead2Length > pHead1Length) {
      tempList1 = pHead2;
      tempList2 = pHead1;
      gap = pHead2Length - pHead1Length;
     }   
     for (int i = 0; i < gap; i++) {
      tempList1 = tempList1.next;
     }   
     while((tempList1 != null) && (tempList2 != null) && (tempList1.val != tempList2.val)) {
      tempList1 = tempList1.next;
      tempList2 = tempList2.next;
     }   
     return tempList1;
     } 
     public int getListLength(ListNode list) {
     int number = 0;
     while(list != null) {
      ++number;
      list = list.next;
     }
     return number;
    }

方法四

用兩個指針掃描”兩個鏈表“,最終兩個指針到達 null 或者到達公共結點。

public ListNode FindFirstCommonNode_3(ListNode pHead1, ListNode pHead2) {
     if(pHead1 == null || pHead2 == null) {
      return null;
     }
     ListNode temp1 = pHead1;
     ListNode temp2 = pHead2;
     while(temp1 != temp2) {
      temp1 = (temp1 == null ? pHead2 : temp1.next); 
      temp2 = (temp2 == null ? pHead1 : temp2.next);
      System.out.println(pHead1.val);
     } 
     return temp1;
    }
發佈了56 篇原創文章 · 獲贊 11 · 訪問量 2041
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章