package jxau.lyx.link;
/**
*
* @author: liyixiang
* @data:2014-10-2
* @题目大意:
* 求两个单链表相交的第一个节点
* @主要思路:
* 对第一个链表遍历,计算长度len1,同时保存最后一个节点的地址。
* 对第二个链表遍历,计算长度len2,同时检查最后一个节点是否和第一个链表的最后一个节点
* 相同,若不相同,不相交,结束。
* 两个链表均从头节点开始,假设len1大于len2,那么将第一个链表先遍历len1-len2个节点
* 此时两个链表当前节点到第一个相交节点的距离就相等了,然后一起向后遍历,直到两个节点
* 的地址相同。
* @时间复杂度:
* O(len1+len2)
*
* ---- len2
* |__________
* |
* --------- len1
*
* |---|<- len1-len2
*
* @空间复杂度:
*/
public class GetFirstCommonNode {
//结点
private static class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
}
}
public static Node getFirstNodeInCycle(Node head) {
Node slow = head;
Node fast = head;
// 1) 找到快慢指针相遇点
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) { // Collision
break;
}
}
// 错误检查,这是没有环的情况
if (fast == null || fast.next == null) {
return null;
}
// 2)现在,相遇点离环的开始处的距离等于链表头到环开始处的距离,
// 这样,我们把慢指针放在链表头,快指针保持在相遇点,然后
// 同速度前进,再次相遇点就是环的开始处!
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
// 再次相遇点就是环的开始处
return fast;
}
}
本题建议画图理解!