问题:
给定两哥可能有环也可能无环的单链表,头节点head1和head2。实现一个函数,如果两个链表相交返回相交的第一个节点,否则返回null。
要求:
如果两个链表之和长度为n,时间复杂度请达到O(n).
解题:
设置两个指针一个快指针(每次走两步)一个慢指针(每次走一步),1:两个链表都无环,循环判断交点,2:一个链表有环一个无环不可能相交。3:两个链表都有环(1)两个独立的环不相交,(2)相交但相交的位置在环以外,(3)两个链表入环的节点是一个,(4)两个链表入环的节点不是一个。
代码:
package class08;
public class Code01_FindFirstIntersectNode {
public static class Node{
public int val;
public Node next;
public Node() {
}
public Node(int data) {
this.val = data;
}
}
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);
else if(loop1!=null&&loop2!=null) {
return haveloop(head1,loop1,head2,loop2);
}
return null;
}
private static Node haveloop(Node head1, Node loop1, Node head2, Node loop2) {
Node cur1 = null;
Node cur2 = null;
if(loop1 == loop2) {
int n = 0;
cur1 = head1;
cur2 = head2;
while(cur1.next!=null) {
n++;
cur1 = cur1.next;
}
while(cur2.next!=null) {
n--;
cur2 = cur2.next;
}
Math.abs(n);
while(n!=0) {
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;
}
private static Node noloop(Node head1, Node head2) {
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;
while(n!=0) {
n--;
cur1 = cur1.next;
}
while(cur1!=cur2) {
cur1 = cur1.next;
cur2 = cur2.next;
}
return cur1;
}
public static Node getloopNode(Node loop) {
if(loop==null||loop.next==null||loop.next.next==null) return null;
Node fast = loop.next.next;
Node slow = loop.next;
while(slow!=fast) {
if(fast.next==null||fast.next.next==null) return null;
slow = slow.next;
fast = fast.next.next;
}
fast = loop;
while(slow!=fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
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);
}
}