//两个单链表相交的一系列问题
public class TwoInterList{
//链表节点的定义
public static class Node{
public int value;
public Node next;
public Node(int data)
{
this.value=data;
}
}
//返回两个链表相交的第一个节点(只有两种情况(1)两个链表都无环相交 (2)两个链表都有环相交)
public static Node getIntersectNode(Node head1,Node head2)
{
if(head1==null||head2==null)
{
return null;
}
Node loop1=getLoop(head1);
Node loop2=getLoop(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 getLoop(Node head)
{
if(head==null||head.next==null||head.next.next==null)
{
return null;
}
//此种解法只对1->2->3->1情况下成立
/**
Node p=head;
while(p.next!=null)
{
p=p.next;
if(p==head)
{
return head;
}
}
*/
Node n1=head.next; // n1->slow (一步一步走)
Node n2=head.next.next; //n2->fast (两步两步走)
while(n1!=n2)
{
if(n2.next==null||n2.next.next==null)
{
return null;
}
n2=n2.next.next;
n1=n1.next;
}
n2=head; //n2 再次指向head
while(n1!=n2)
{
n1=n1.next;
n2=n2.next;
}
return n1;
}
//问题二、检验两个无环链表是否相交,并且返回两个链表相交的第一个节点
public static Node noLoop(Node head1,Node head2)
{
if(head1==null||head2==null)
{
return null;
}
Node cur1=head1;
Node cur2=head2;
int n=0;
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);
//较长的链表的链表先走n步
while(n!=0)
{
--n;
cur1=cur1.next;
}
while(cur1!=cur2)
{
cur1=cur1.next;
cur2=cur2.next;
}
return cur1;
}
//问题三:判断两个有环链表是否相交,相交则返回第一个相交节点
public static Node bothLoop(Node head1,Node loop1,Node head2,Node loop2)
{
Node cur1=null;
Node cur2=null;
if(loop1==loop2)
{
cur1=head1;
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{
cur1=loop1.next;
while(cur1!=loop1)
{
if(cur1!=loop2)
{
return loop1;
}
cur1=cur1.next;
}
return null;
}
}
public static void main(String[] args)
{
//System.out.println("Hello");
Node node=new Node(1);
node.next=new Node(2);
node.next.next=new Node(3);
node.next.next.next=node.next;
Node mode=new Node(1);
mode.next=new Node(2);
mode.next.next=new Node(3);
mode.next.next.next=new Node(4);
mode.next.next.next.next=mode.next;
System.out.println(getIntersectNode(node,mode).value);
}
}