diff --git a/src/ds/linklist/CircleLinkList.java b/src/ds/linklist/CircleLinkList.java deleted file mode 100644 index 76ca77c..0000000 --- a/src/ds/linklist/CircleLinkList.java +++ /dev/null @@ -1,34 +0,0 @@ -package ds.linklist; - -/** - * 环形链表 - * @author Wen - * @date 2022/8/31 23:27 - */ - -public class CircleLinkList { - - /** - * 链表是否有环 - * @return 第一个入环节点 - */ - public Node hasCircle(Node head) { - if (head == null || head.next == null) { - return null; - } - Node slow = head, quick = head.next; - while (slow != quick) { - if (slow == null || quick == null) { - return null; - } - slow = slow.next; - quick = quick.next.next; - } - quick = head; - while (slow != quick) { - slow = slow.next; - quick = quick.next; - } - return slow; - } -} diff --git a/src/ds/linklist/CircleLinkListQ.java b/src/ds/linklist/CircleLinkListQ.java index 72e6673..5944b1d 100644 --- a/src/ds/linklist/CircleLinkListQ.java +++ b/src/ds/linklist/CircleLinkListQ.java @@ -14,5 +14,38 @@ package ds.linklist; * @date 2022/8/31 23:45 */ public class CircleLinkListQ { + private final CircleLinkListUtil util = new CircleLinkListUtil(); + public Node findFirstIntersectNode(Node head1, Node head2) { + if (head1 == null || head2 == null) { + return null; + } + if (util.hasCircle(head1) == null && util.hasCircle(head2) == null) { + return util.bothNoCircle(head1, head2, null); + } else if (util.hasCircle(head1) != null && util.hasCircle(head2) != null) { + return util.bothCircle(head1, head2); + } + return null; + } + + public static void main(String[] args) { + CircleLinkListQ circleLinkListQ = new CircleLinkListQ(); + Node node1 = new Node(1); + Node node2 = new Node(2); + Node node3 = new Node(3); + Node node4 = new Node(4); + Node node5 = new Node(5); + Node node6 = new Node(6); + Node node7 = new Node(7); + Node node8 = new Node(8); + Node node9 = new Node(9); + node1.next = node2; + node2.next = node3; + node3.next = node4; + node4.next = node5; + node5.next = node3; + node6.next = node7; + node7.next = node5; + System.out.println(circleLinkListQ.findFirstIntersectNode(node1, node6).val); + } } diff --git a/src/ds/linklist/CircleLinkListUtil.java b/src/ds/linklist/CircleLinkListUtil.java new file mode 100644 index 0000000..9c302c1 --- /dev/null +++ b/src/ds/linklist/CircleLinkListUtil.java @@ -0,0 +1,92 @@ +package ds.linklist; + +/** + * 环形链表 + * + * @author Wen + * @date 2022/8/31 23:27 + */ + +public class CircleLinkListUtil { + + /** + * 链表是否有环 + * + * @return 第一个入环节点 + */ + public Node hasCircle(Node head) { + if (head == null || head.next == null || head.next.next == null) { + return null; + } + Node slow = head.next, quick = head.next.next; + while (slow != quick) { + if (slow == null || quick.next == null) { + return null; + } + slow = slow.next; + quick = quick.next.next; + } + quick = head; + while (slow != quick) { + slow = slow.next; + quick = quick.next; + } + return slow; + } + + public Node bothNoCircle(Node h1, Node h2, Node tail) { + if (h1 == null || h2 == null) { + return null; + } + int length1 = 1, length2 = 1; + Node n1 = h1, n2 = h2; + while (n1.next != tail) { + length1++; + n1 = n1.next; + } + while (n2.next != tail) { + length2++; + n2 = n2.next; + } + if (n1 == n2) { + n1 = length1 <= length2 ? h1 : h2; + n2 = n1 == h1 ? h2 : h1; + } + //长路径先走多出来的步数 + int i = 0; + int remain = Math.abs(length1 - length2); + while (i < remain) { + n2 = n2.next; + i++; + } + while (n1.next != null && n2.next != null) { + if (n1 == n2) { + return n1; + } + n1 = n1.next; + n2 = n2.next; + } + return n1; + } + + public Node bothCircle(Node h1, Node h2) { + Node c1 = hasCircle(h1); + Node c2 = hasCircle(h2); + Node l1 = c1.next; + while (l1 != c1) { + if (l1 == c2) { + break; + } + l1 = l1.next; + } + //两个不相交的环 + if (l1 != c2) return null; + //两个环相交 + //1.入环节点为同一节点 + if (c1 == c2) { + return bothNoCircle(h1, h2, l1); + } else { + return c1; + } + } +}