【九度OJ1505】|【劍指offer37】兩個鏈表的第一個公共結點

題目描述: java

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

輸入:

輸入可能包含多個測試樣例。
對於每一個測試案例,輸入的第一行爲兩個整數m和n(1<=m,n<=1000):表明將要輸入的兩個鏈表的元素的個數。
接下來的兩行,第一行爲第一個鏈表的全部元素,中間用空格隔開。第二行爲第二個鏈表的全部元素,中間用空格隔開。 測試

輸出:

對應每一個測試案例,
輸出兩個鏈表的第一個公共結點的值。
若是兩個鏈表沒有公共結點,則輸出「My God」。 code

樣例輸入:
5 4
1 2 3 6 7
4 5 6 7
3 3
1 5 7
2 4 7
2 3
1 3
4 5 6
樣例輸出:
6
7
My God
解析:

    看到這個題目,第一反應就是蠻力法:在第一鏈表上順序遍歷每一個結點。每遍歷一個結點的時候,在第二個鏈表上順序遍歷每一個結點。若是此時兩個鏈表上的結點是同樣的,說明此時兩個鏈表重合,因而找到了它們的公共結點。若是第一個鏈表的長度爲m,第二個鏈表的長度爲n,顯然,該方法的時間複雜度爲O(mn)。 同步

    接 下來咱們試着去尋找一個線性時間複雜度的算法。咱們先把問題簡化:如何判斷兩個單向鏈表有沒有公共結點?前面已經提到,若是兩個鏈表有一個公共結點,那麼 該公共結點以後的全部結點都是重合的。那麼,它們的最後一個結點必然是重合的。所以,咱們判斷兩個鏈表是否是有重合的部分,只要分別遍歷兩個鏈表到最後一 個結點。若是兩個尾結點是同樣的,說明它們用重合;不然兩個鏈表沒有公共的結點。 io

    在上面的思路中,順序遍歷兩個鏈表到尾結點的時候,咱們不能保證在兩個鏈表上同時到達尾結點。這是由於兩個鏈表不必定長度同樣。但若是假設一個鏈表比另外一個長l個結點,咱們先在長的鏈表上遍歷l個結點,以後再同步遍歷,這個時候咱們就能保證同時到達最後一個結點了。因爲兩個鏈表從第一個公共結點考試到鏈表的尾結點,這一部分是重合的。所以,它們確定也是同時到達第一公共結點的。因而在遍歷中,第一個相同的結點就是第一個公共的結點。 class

    在這個思路中,咱們先要分別遍歷兩個鏈表獲得它們的長度,並求出兩個長度之差。在長的鏈表上先遍歷若干次以後,再同步遍歷兩個鏈表,知道找到相同的結點,或者一直到鏈表結束。此時,若是第一個鏈表的長度爲m,第二個鏈表的長度爲n,該方法的時間複雜度爲O(m+n)。 import

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
 
/**
 * 兩個鏈表的第一個公共結點
 * 2014年3月17日 22:09:38
 * @author aqia358
 *
 */
public class Main {
 
    static class Node{
        public int value;
        public Node next = null;
    }
    public static void find(Node a, Node b, int m, int n){
        Node l = new Node();
        Node s = new Node();
        int p = 0;
        if(m > n){
            l = a;
            s = b;
            p = m - n;
        }else{
            l = b;
            s = a;
            p = n - m;
        }
        while(p > 0){
            p--;
            l = l.next;
        }
        while(l.next != null && l.value != s.value){
            l = l.next;
            s = s.next;
        }
        if(l.next == null)
            System.out.println("My God");
        else
            System.out.println(l.value);
    }
     
     
    public static void main(String[] args) throws IOException {
        StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        while(st.nextToken() != st.TT_EOF){
            int m = (int) st.nval;
            st.nextToken();
            int n = (int) st.nval;
            Node a = new Node();
            Node a1 = a;
            Node b = new Node();
            Node b1 = b;
            for(int i = 0; i < m; i++){
                st.nextToken();
                a1.value = (int) st.nval;
                a1.next = new Node();
                a1 = a1.next;
            }
            for(int j = 0; j < n; j++){
                st.nextToken();
                b1.value = (int) st.nval;
                b1.next = new Node();
                b1 = b1.next;
            }
            Main.find(a, b, m, n);
        }
    }
 
}
 
/**************************************************************
    Problem: 1505
    User: aqia358
    Language: Java
    Result: Accepted
    Time:910 ms
    Memory:27504 kb
****************************************************************/
相關文章
相關標籤/搜索