【九度OJ 1505】|【剣指offer 37】2つのチェーンテーブルの最初の共通ノード
3621 ワード
タイトルの説明:
2つのチェーンテーブルを入力し、最初の共通ノードを見つけます.
入力:
入力には、複数のテストサンプルが含まれる場合があります.各テストケースについて、入力される第1の動作の2つの整数mおよびn(1<=m、n<=1000):入力する2つのチェーンテーブルの要素の数を表す.次の2行は、最初の動作の最初のチェーンテーブルのすべての要素で、中央はスペースで区切られています.2番目の動作2番目のチェーンテーブルのすべての要素は、スペースで区切られています.
出力:
各テストケースに対応して、2つのチェーンテーブルの最初の共通ノードの値を出力します.2つのチェーンテーブルに共通のノードがない場合は、「My God」が出力されます.
サンプル入力:
サンプル出力:
この問題を見て、第一反応は蛮力法です:第一鎖表の上で順番に各結点を遍歴します.1つのノードを巡回するたびに、2番目のチェーンテーブルに各ノードを順次巡回します.このとき、2つのチェーンテーブルのノードが同じである場合、2つのチェーンテーブルが重なることを示し、共通のノードが見つかりました.第1のチェーンテーブルの長さがm,第2のチェーンテーブルの長さがnの場合,この方法の時間的複雑さはO(mn)であることは明らかである.
次に,線形時間複雑度のアルゴリズムを探してみた.まず問題を簡略化します.2つの一方向チェーンテーブルに共通のノードがあるかどうかをどのように判断しますか.前述したように、2つのチェーンテーブルに共通のノードがある場合、共通のノードの後にあるすべてのノードは一致します.では、それらの最後のノードは必ず重なる.そこで,2つのチェーンテーブルが重なり合う部分があるかどうかを判断し,それぞれ2つのチェーンテーブルを最後のノードまで遍歴すればよい.2つのテールノードが同じであれば、それらが重なることを示します.そうでなければ、2つのチェーンテーブルには共通のノードがありません.
上記の考え方では,2つのチェーンテーブルからテールノードまで順次遍歴する場合,2つのチェーンテーブル上で同時にテールノードに到達することは保証できない.これは、2つのチェーンテーブルが必ずしも同じ長さではないからです.しかし、あるチェーンテーブルが別の長いl個のノードよりも長いと仮定すると、私たちはまず長いチェーンテーブル上でl個のノードを遍歴し、その後同期して遍歴し、この時私たちは同時に最後のノードに着くことを保証することができます.2つのチェーンテーブルは、最初の共通ノード試験からチェーンテーブルの末尾ノードまで、この部分が重なるためです.したがって、それらも同時に第1の共通ノードに到着したに違いない.そこで遍歴では,最初の同じノードが最初の共通のノードである.
この考え方では,まず2つのチェーンテーブルをそれぞれ遍歴してそれらの長さを求め,2つの長さの差を求めた.長いチェーンテーブルを何回か巡回した後、2つのチェーンテーブルを同期して巡回し、同じノードが見つかるか、チェーンテーブルが終わるまで待機します.このとき,第1のチェーンテーブルの長さがm,第2のチェーンテーブルの長さがnの場合,この方法の時間的複雑度はO(m+n)である.
2つのチェーンテーブルを入力し、最初の共通ノードを見つけます.
入力:
入力には、複数のテストサンプルが含まれる場合があります.各テストケースについて、入力される第1の動作の2つの整数mおよびn(1<=m、n<=1000):入力する2つのチェーンテーブルの要素の数を表す.次の2行は、最初の動作の最初のチェーンテーブルのすべての要素で、中央はスペースで区切られています.2番目の動作2番目のチェーンテーブルのすべての要素は、スペースで区切られています.
出力:
各テストケースに対応して、2つのチェーンテーブルの最初の共通ノードの値を出力します.2つのチェーンテーブルに共通のノードがない場合は、「My God」が出力されます.
サンプル入力:
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
解析:この問題を見て、第一反応は蛮力法です:第一鎖表の上で順番に各結点を遍歴します.1つのノードを巡回するたびに、2番目のチェーンテーブルに各ノードを順次巡回します.このとき、2つのチェーンテーブルのノードが同じである場合、2つのチェーンテーブルが重なることを示し、共通のノードが見つかりました.第1のチェーンテーブルの長さがm,第2のチェーンテーブルの長さがnの場合,この方法の時間的複雑さはO(mn)であることは明らかである.
次に,線形時間複雑度のアルゴリズムを探してみた.まず問題を簡略化します.2つの一方向チェーンテーブルに共通のノードがあるかどうかをどのように判断しますか.前述したように、2つのチェーンテーブルに共通のノードがある場合、共通のノードの後にあるすべてのノードは一致します.では、それらの最後のノードは必ず重なる.そこで,2つのチェーンテーブルが重なり合う部分があるかどうかを判断し,それぞれ2つのチェーンテーブルを最後のノードまで遍歴すればよい.2つのテールノードが同じであれば、それらが重なることを示します.そうでなければ、2つのチェーンテーブルには共通のノードがありません.
上記の考え方では,2つのチェーンテーブルからテールノードまで順次遍歴する場合,2つのチェーンテーブル上で同時にテールノードに到達することは保証できない.これは、2つのチェーンテーブルが必ずしも同じ長さではないからです.しかし、あるチェーンテーブルが別の長いl個のノードよりも長いと仮定すると、私たちはまず長いチェーンテーブル上でl個のノードを遍歴し、その後同期して遍歴し、この時私たちは同時に最後のノードに着くことを保証することができます.2つのチェーンテーブルは、最初の共通ノード試験からチェーンテーブルの末尾ノードまで、この部分が重なるためです.したがって、それらも同時に第1の共通ノードに到着したに違いない.そこで遍歴では,最初の同じノードが最初の共通のノードである.
この考え方では,まず2つのチェーンテーブルをそれぞれ遍歴してそれらの長さを求め,2つの長さの差を求めた.長いチェーンテーブルを何回か巡回した後、2つのチェーンテーブルを同期して巡回し、同じノードが見つかるか、チェーンテーブルが終わるまで待機します.このとき,第1のチェーンテーブルの長さがm,第2のチェーンテーブルの長さがnの場合,この方法の時間的複雑度はO(m+n)である.
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
****************************************************************/