You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

529 lines
14 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package leo.class10;
class Node{
int value;
Node next;
public Node(int v){
this.value = v;
}
}
/**
* @author Leo
* @ClassName FindFirstIntersectNode
* @DATE 2020/12/4 2:26 下午
* @Description
* 给定两个可能有环也可能无环的单链表头节点head1和head2。请实现一个函数如果两个链表相交请返回相交的 第一个节点。如果不相交返回null
* 【要求】
* 如果两个链表长度之和为N时间复杂度请达到O(N),额外空间复杂度 请达到O(1)。
*/
public class FindFirstIntersectNode {
public static Node getIntersectNode(Node head1, Node head2) {
if (head1 == null || head2 == null) {
return null;
}
// judgment node is there a ring
Node loop1 = getLoop(head1);
Node loop2 = getLoop(head2);
//judgment different situations
if (loop1 == null && loop2 == null) {
//无环
return noLoop(head1, head2);
} else if (loop1 != null && loop2 != null) {
//有环
return bothLoop(head1, loop1, head2, loop2);
}
return null;
}
private static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {
if (head1 == null || head2 == null) {
return null;
}
Node cur1 = null;
Node cur2 = null;
if (loop1 == loop2) {
cur1 = head1;
cur2 = head2;
int n = 0;
while (cur1 != loop1) {
cur1 = cur1.next;
n++;
}
while (cur2 != loop2) {
cur2 = cur2.next;
n--;
}
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 Node getLoop(Node head) {
if (head == null || head.next == null || head.next.next == null) {
return null;
}
Node slow = head.next;
Node fast = head.next.next;
while (slow != fast) {
if (fast.next == null || fast.next.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
}
fast = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
public static Node noLoop(Node head1, Node head2) {
if (head1 == null || head2 == null) {
return null;
}
int n = 0;
Node cur1 = head1;
Node cur2 = head2;
while (cur1 != null) {
n++;
cur1 = cur1.next;
}
while (cur2 != 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) {
n--;
cur1 = cur1.next;
}
while (cur1 != cur2) {
cur1 = cur1.next;
cur2 = cur2.next;
}
return cur1;
}
}
class FindFirstIntersectNode1{
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 bothLoop(head1, loop1, head2, loop2);
} else if (loop1 == null && loop2 == null) {
return noLoop(head1, head2);
}
return null;
}
public static Node bothLoop(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 != 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) {
cur1 = cur1.next;
n--;
}
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 Node noLoop(Node head1, Node head2) {
if (head1 == null || head2 == null) {
return null;
}
int n = 0;
Node cur1 = head1;
while (cur1 != null) {
n++;
cur1 = cur1.next;
}
Node cur2 = head2;
while (cur2 != 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) {
n--;
cur1 = cur1.next;
}
while (cur1 != cur2) {
cur1 = cur1.next;
cur2 = cur2.next;
}
return cur1;
}
public static Node getLoop(Node head) {
if (head == null || head.next == null || head.next.next == null) {
return null;
}
Node slow = head.next;
Node fast = head.next.next;
while (slow != fast) {
if (fast.next == null || fast.next.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
}
fast = head;
while (fast != slow) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
class FindFirstIntersectNode2{
public static Node getIntersectNode(Node head1,Node head2){
if (head1 == null || head1.next == null || head1.next.next == null) {
return null;
}
if (head2 == null || head2.next == null || head2.next.next == null) {
return null;
}
Node loop1 = getLoop(head1);
Node loop2 = getLoop(head2);
if (loop1 != null && loop2 != null) {
return bothLoop(head1, loop1, head2, loop2);
} else if (loop1 == null && loop2 == null) {
return noLoop(head1, head2);
}
return null;
}
public static Node getLoop(Node head) {
if (head == null || head.next == null || head.next.next == null) {
return null;
}
Node slow = head.next;
Node fast = head.next.next;
while (slow != fast) {
if (fast.next == null || fast.next.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
}
fast = head;
while(fast!=slow){
slow = slow.next;
fast = fast.next;
}
return slow;
}
private static Node noLoop(Node head1, Node head2) {
int n = 0;
Node cur1 = head1;
Node cur2 = head2;
while (cur1 != null) {
cur1 = cur1.next;
n++;
}
while (cur2 != null) {
cur2 = cur2.next;
n--;
}
if (cur1 != cur2) {
return null;
}
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;
}
private static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) {
if (loop1 != loop2) {
Node cur = loop1.next;
while (cur != loop1) {
if (cur == loop2) {
return loop1;
}
cur = cur.next;
}
return null;
}else{
Node cur1 = head1;
Node cur2 = head2;
int n = 0;
while (cur1 != loop1) {
n++;
cur1 = cur1.next;
}
while (cur2 != loop2) {
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;
}
}
}
class FindFirstIntersectNode3{
public static Node getIntersectNode(Node head1, Node head2) {
if (head1 == null || head1.next == null || head1.next.next == null) {
return null;
}
if (head2 == null || head2.next == null || head1.next.next == null) {
return null;
}
Node loop1 = getLoop(head1);
Node loop2 = getLoop(head2);
if (loop1 == null && loop2 == null) {
return noLoop(head1, head2);
} else if (loop1 != null & loop2 != null) {
return bothLoop(head1, loop1, head2, loop2);
}
return null;
}
public static Node getLoop(Node head) {
if (head == null) {
return null;
}
Node slow = head.next;
Node fast = head.next.next;
while (slow != fast) {
if (fast.next == null || fast.next.next == null) {
return null;
}
slow = slow.next;
fast = fast.next.next;
}
fast = head;
while (fast != slow) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
public static Node noLoop(Node head1, Node head2) {
if (head1 == null || head1.next == null || head1.next.next == null) {
return null;
}
if (head2 == null || head2.next == null || head2.next.next == null) {
return null;
}
int n = 0;
Node cur1 = head1;
Node cur2 = head2;
while (cur1 != null) {
n++;
cur1 = cur1.next;
}
while (cur2 != 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) {
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;
Node cur2;
if (loop1 == loop2) {
cur1 = head1;
cur2 = head2;
int n = 0;
while (cur1 != loop1) {
cur1 = cur1.next;
n++;
}
while (cur2 != loop2) {
cur2 = cur2.next;
n--;
}
if (cur1 != cur2) {
return null;
}
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;
}
}
}
class FindFirstIntersectNode_Main{
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(FindFirstIntersectNode3 .getIntersectNode(head1, head2).value);
// 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(FindFirstIntersectNode3.getIntersectNode(head1, head2).value);
// 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(FindFirstIntersectNode3.getIntersectNode(head1, head2).value);
}
}