【九度OJ1505】|【剑指offer37】两个链表的第一个公共结点
2014-03-19 00:00
375 查看
题目描述:
输入两个链表,找出它们的第一个公共结点。
输入:
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的两个链表的元素的个数。
接下来的两行,第一行为第一个链表的所有元素,中间用空格隔开。第二行为第二个链表的所有元素,中间用空格隔开。
输出:
对应每个测试案例,
输出两个链表的第一个公共结点的值。
如果两个链表没有公共结点,则输出“My God”。
样例输入:
样例输出:
看到这个题目,第一反应就是蛮力法:在第一链表上顺序遍历每个结点。每遍历一个结点的时候,在第二个链表上顺序遍历每个结点。如果此时两个链表上的结点是一样的,说明此时两个链表重合,于是找到了它们的公共结点。如果第一个链表的长度为m,第二个链表的长度为n,显然,该方法的时间复杂度为O(mn)。
接 下来我们试着去寻找一个线性时间复杂度的算法。我们先把问题简化:如何判断两个单向链表有没有公共结点?前面已经提到,如果两个链表有一个公共结点,那么 该公共结点之后的所有结点都是重合的。那么,它们的最后一个结点必然是重合的。因此,我们判断两个链表是不是有重合的部分,只要分别遍历两个链表到最后一 个结点。如果两个尾结点是一样的,说明它们用重合;否则两个链表没有公共的结点。
在上面的思路中,顺序遍历两个链表到尾结点的时候,我们不能保证在两个链表上同时到达尾结点。这是因为两个链表不一定长度一样。但如果假设一个链表比另一个长l个结点,我们先在长的链表上遍历l个结点,之后再同步遍历,这个时候我们就能保证同时到达最后一个结点了。由于两个链表从第一个公共结点考试到链表的尾结点,这一部分是重合的。因此,它们肯定也是同时到达第一公共结点的。于是在遍历中,第一个相同的结点就是第一个公共的结点。
在这个思路中,我们先要分别遍历两个链表得到它们的长度,并求出两个长度之差。在长的链表上先遍历若干次之后,再同步遍历两个链表,知道找到相同的结点,或者一直到链表结束。此时,如果第一个链表的长度为m,第二个链表的长度为n,该方法的时间复杂度为O(m+n)。
输入两个链表,找出它们的第一个公共结点。
输入:
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的两个链表的元素的个数。
接下来的两行,第一行为第一个链表的所有元素,中间用空格隔开。第二行为第二个链表的所有元素,中间用空格隔开。
输出:
对应每个测试案例,
输出两个链表的第一个公共结点的值。
如果两个链表没有公共结点,则输出“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解析:
看到这个题目,第一反应就是蛮力法:在第一链表上顺序遍历每个结点。每遍历一个结点的时候,在第二个链表上顺序遍历每个结点。如果此时两个链表上的结点是一样的,说明此时两个链表重合,于是找到了它们的公共结点。如果第一个链表的长度为m,第二个链表的长度为n,显然,该方法的时间复杂度为O(mn)。
接 下来我们试着去寻找一个线性时间复杂度的算法。我们先把问题简化:如何判断两个单向链表有没有公共结点?前面已经提到,如果两个链表有一个公共结点,那么 该公共结点之后的所有结点都是重合的。那么,它们的最后一个结点必然是重合的。因此,我们判断两个链表是不是有重合的部分,只要分别遍历两个链表到最后一 个结点。如果两个尾结点是一样的,说明它们用重合;否则两个链表没有公共的结点。
在上面的思路中,顺序遍历两个链表到尾结点的时候,我们不能保证在两个链表上同时到达尾结点。这是因为两个链表不一定长度一样。但如果假设一个链表比另一个长l个结点,我们先在长的链表上遍历l个结点,之后再同步遍历,这个时候我们就能保证同时到达最后一个结点了。由于两个链表从第一个公共结点考试到链表的尾结点,这一部分是重合的。因此,它们肯定也是同时到达第一公共结点的。于是在遍历中,第一个相同的结点就是第一个公共的结点。
在这个思路中,我们先要分别遍历两个链表得到它们的长度,并求出两个长度之差。在长的链表上先遍历若干次之后,再同步遍历两个链表,知道找到相同的结点,或者一直到链表结束。此时,如果第一个链表的长度为m,第二个链表的长度为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 ****************************************************************/
相关文章推荐
- 【九度】题目1505:两个链表的第一个公共结点
- 剑指Offer - 九度1505 - 两个链表的第一个公共结点
- 题目1505:两个链表的第一个公共结点-九度
- 九度题目1505:两个链表的第一个公共结点
- 九度 题目1505:两个链表的第一个公共结点
- 九度题目1505:两个链表的第一个公共结点
- 九度OJ-题目1505:两个链表的第一个公共结点
- 九度OJ 1505 两个链表的第一个公共结点 【数据结构】
- 九度OJ 1505 两个链表的第一个公共结点 【数据结构】
- 题目1505:两个链表的第一个公共结点
- 剑指offer37题(两个链表的第一个公共结点)
- 剑指offer- 题目1505:两个链表的第一个公共结点 (2014.1.1)
- 两个链表的第一个公共结点(剑指offer37)
- 【剑指Offer面试编程题】题目1505:两个链表的第一个公共结点--九度OJ
- 【剑指Offer面试编程题】题目1505:两个链表的第一个公共结点--九度OJ
- 两个链表的第一个公共结点
- 两个链表的第一个公共结点
- 牛客网剑指offer-两个链表的第一个公共结点
- 剑指offer_链表---两个链表的第一个公共结点
- 面试题37:两个链表的第一个公共结点