思路:一个链表可能有环也有可能没环,我们要首先判断是否有环。如果两个都没有环,则用无环链表的方式进行判断;如果一个有环,一个没环,则肯定不存在相交的问题;两个都有环的话,采用有环的方式就行判断。
无环的判断方式:先看一下两个链表的长度,然后让长链表先走n步,然后开始判断是否相等。
有环的判断方式:先看一下环的起点是否一样,如果一样,则转化为无环的判断方式;若不一样则遍历其中一个环,看看是否能够遇到另一个环的起点,遇到的话则返回true,没遇到就返回false。
package lianxi03;
public class Code12_FindFirstNode {
public static void main(String[] args) {
// 1->2->3->4->5->6->7->null
Node head1 = new Node(1);
head1.next = new Node(2);
head1.next.next = new Node(3);
head1.next.next.next = new Node(4);
head1.next.next.next.next = new Node(5);
head1.next.next.next.next.next = new Node(6);
head1.next.next.next.next.next.next = new Node(7);
// 0->9->8->6->7->null
Node head2 = new Node(0);
head2.next = new Node(9);
head2.next.next = new Node(8);
head2.next.next.next = head1.next.next.next.next.next; // 8->6
System.out.println(getIntersectNode(head1, head2).val);
// 1->2->3->4->5->6->7->4...
head1 = new Node(1);
head1.next = new Node(2);
head1.next.next = new Node(3);
head1.next.next.next = new Node(4);
head1.next.next.next.next = new Node(5);
head1.next.next.next.next.next = new Node(6);
head1.next.next.next.next.next.next = new Node(7);
head1.next.next.next.next.next.next = head1.next.next.next; // 7->4
// 0->9->8->2...
head2 = new Node(0);
head2.next = new Node(9);
head2.next.next = new Node(8);
head2.next.next.next = head1.next; // 8->2
System.out.println(getIntersectNode(head1, head2).val);
// 0->9->8->6->4->5->6..
head2 = new Node(0);
head2.next = new Node(9);
head2.next.next = new Node(8);
head2.next.next.next = head1.next.next.next.next.next; // 8->6
System.out.println(getIntersectNode(head1, head2).val);
}
public static class Node{
int val;
Node next;
public Node(int data){
this.val=data;
}
}
public static Node getLoopNode(Node head){
if(head==null||head.next==null)return null;
Node fast=head.next.next;
Node slow=head.next;
while(fast!=slow){
if(fast.next==null||fast.next.next==null){
return null;
}
if(fast==slow){
fast=head;
break;
}
fast=fast.next.next;
slow=slow.next;
}
while(fast!=slow){
fast=fast.next;
slow=slow.next;
}
return fast;
}
public static Node getIntersectNode(Node head1,Node head2){
if(head1==null||head2==null)return null;
Node loop1=getLoopNode(head1);
Node loop2=getLoopNode(head2);
if(loop1==null&&loop2==null)
return noloop(head1,head2);
if(loop1!=null&&loop2!=null)
return bothloop(head1,loop1,head2,loop2);
return null;
}
public static Node noloop(Node head1,Node head2){
int n=0;
Node cur1=head1;
Node cur2=head2;
while(cur1.next!=null){
n++;
cur1=cur1.next;
}
while(cur2.next!=null){
n--;
cur2=cur2.next;
}
if(cur1!=cur2) return null;
cur1=n>0?head1:head2;
cur2=cur1==head1?head2:head1;
n=Math.abs(n);
while(n!=0){
cur1=cur1.next;n--;
}
while(cur1!=cur2){
cur1=cur1.next;
cur2=cur2.next;
}
return cur1;
}
public static Node bothloop(Node head1,Node loop1,Node head2,Node loop2){
if(loop1==loop2){
Node cur1=head1;
Node cur2=head2;
int n=0;
while(cur1!=loop1){
n++;
cur1=cur1.next;
}
while(cur2!=loop2){
n--;
cur2=cur2.next;
}
cur1=n>0?head1:head2;
cur2=cur1==head1?head2:head1;
n=Math.abs(n);
while(n!=0){
n--;
cur1=cur1.next;
}
while(cur1!=cur2){
cur1=cur1.next;
cur2=cur2.next;
}
return cur1;
}else{
Node cur1=loop1.next;
while(cur1!=loop1){
if(cur1==loop2)
return loop1;
cur1=cur1.next;
}
return null;
}
}
}