【九度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
****************************************************************/
相关文章
相关标签/搜索