【Java】 劍指offer(52) 兩個鏈表的第一個公共結點

 

本文參考自《劍指offer》一書,代碼採用Java語言。html

更多:《劍指Offer》Java實現合集  java

題目

  輸入兩個鏈表,找出它們的第一個公共結點。post

思路

  蠻力法:遍歷第一個鏈表的結點,每到一個結點,就在第二個鏈表上遍歷每一個結點,判斷是否相等。時間複雜度爲O(m*n),效率低;測試

  使用棧:因爲公共結點出如今尾部,因此用兩個棧分別放入兩個鏈表中的結點,從尾結點開始出棧比較。時間複雜度O(m+n),空間複雜度O(m+n)。this

  利用長度關係:計算兩個鏈表的長度之差,長鏈表先走相差的步數,以後長短鏈表同時遍歷,找到的第一個相同的結點就是第一個公共結點。url

  利用兩個指針:一個指針順序遍歷list1和list2,另外一個指針順序遍歷list2和list1,(這樣兩指針可以保證最終同時走到尾結點),兩個指針找到的第一個相同結點就是第一個公共結點。指針

 

測試算例 htm

  1.功能測試(有/無公共結點;公共結點分別在鏈表的中間,頭結點和尾結點)blog

  2.特殊測試(頭結點爲null)get

完整Java代碼

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

public class FirstCommonNodesInLists {
	public class ListNode{
	    int val;
	    ListNode next = null;
	    ListNode(int val) {
	        this.val = val;
	    }
	}
    
    //方法1:利用長度關係
    public ListNode findFirstCommonNode1(ListNode pHead1, ListNode pHead2) {
        int length1 = getLength(pHead1);
        int length2 = getLength(pHead2);
        int lengthDif = length1-length2;
        ListNode longList = pHead1;
        ListNode shortList = pHead2;
        if(lengthDif<0){
            longList = pHead2;
            shortList = pHead1;
            lengthDif = -lengthDif;
        }
        for(int i=0;i<lengthDif;i++)
            longList = longList.next;
        while(longList!=null && longList!=shortList ){
            longList=longList.next;
            shortList=shortList.next;
        }
        return longList;  //沒有公共結點恰好是null
    }
    
    private int getLength(ListNode head){
        int len=0;
        while(head!=null){
            len++;
            head=head.next;
        }
        return len;
    }

    //方法2:兩個指針,p1順序遍歷list1和list2;p2順序遍歷list2和list1;最終必定會相遇
    public ListNode findFirstCommonNode2(ListNode pHead1, ListNode pHead2) {
        ListNode p1=pHead1;
        ListNode p2=pHead2;
        while(p1!=p2){
            p1= p1==null ? pHead2 : p1.next;
            p2= p2==null ? pHead1 : p2.next;
        }
        return p1;
    }
}

  

收穫

  1.因爲有共同結點時,後面的鏈表是重合的,因此這道題關鍵是要保證最後同時遍歷到達尾結點,所以就有了後面三種方法:

  利用棧的先進後出實現同時到達;

  利用長度關係,長鏈表先行幾步,實現同時到達;

  兩個指針同時遍歷兩個鏈表,一個先list1後list2,另外一個則相反,也能夠實現同時到達。

  

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索