題目描述: 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 ****************************************************************/