From 8772be1c109c16b3268f37afe7fb41b745b56a89 Mon Sep 17 00:00:00 2001 From: whai Date: Mon, 1 Jan 2024 15:35:22 +0800 Subject: [PATCH] =?UTF-8?q?[142.=20=E7=8E=AF=E5=BD=A2=E9=93=BE=E8=A1=A8=20?= =?UTF-8?q?II](https://leetcode.cn/problems/linked-list-cycle-ii/)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 1. 为什么快慢指针一定会相遇? - `V_fast = 2`、`V_slow = 1` 相对速度为1,就一定会相遇 ## 2. 为什么慢指针一圈就能一定能被追上? 两个角度: 1. `|fast- slow| < 1 圈` 所以slow在环内走不会超过一周 2. 慢指针走一圈,快指针走两圈,早就遇上了。 --- .../leetCode/LinkedList/LeetCode142.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode142.java diff --git a/src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode142.java b/src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode142.java new file mode 100644 index 0000000..6e3ce3a --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/LinkedList/LeetCode142.java @@ -0,0 +1,99 @@ +package cn.whaifree.leetCode.LinkedList; + +import cn.whaifree.leetCode.model.ListNode; +import org.junit.Test; + +import java.util.HashSet; +import java.util.Objects; + +public class LeetCode142 { + + @Test + public void test() { + Solution solution = new Solution(); + ListNode listNode1= new ListNode(1); + ListNode listNode2= new ListNode(2,listNode1); + ListNode listNode3= new ListNode(3,listNode2); + ListNode listNode4= new ListNode(4,listNode3); + listNode1.next = listNode3; + +// ListNode.printList(listNode4); + + ListNode listNode = solution.detectCycle(listNode4); + if (listNode == null) { + System.out.println("null"); + } else { + System.out.println(listNode.val); + } + } + + /** + * Definition for singly-linked list. + * class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { + * val = x; + * next = null; + * } + * } + */ + public class Solution { + /** + * 快慢指针 + * 时间复杂度:O(N),其中 N 为链表中节点的数目。我们恰好需要访问链表中的每一个节点。 + * 空间复杂度:O(1) + * + * @param head + * @return + */ + public ListNode detectCycle(ListNode head) { + + ListNode slow = head; + ListNode fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + // 相遇了,有环。 + if (slow == fast) { + break; + } + } + + if (Objects.isNull(fast) || Objects.isNull(fast.next)) { + return null; + } + + // 此时相遇 fast,slow + // x = (n-1)(y-z)+z + slow = head; + while (slow != fast) { + slow = slow.next; + fast = fast.next; + } + return slow; + } + } + + + /** + * 时间复杂度:O(N),其中 N 为链表中节点的数目。我们恰好需要访问链表中的每一个节点。 + * 空间复杂度:O(N),其中 N 为链表中节点的数目。我们需要将链表中的每个节点都保存在哈希表当中。 + */ + public class Solution1 { + /** + * 快慢指针 + * @param head + * @return + */ + public ListNode detectCycle(ListNode head) { + HashSet listNodes = new HashSet<>(); + ListNode index = head; + while (index != null && !listNodes.contains(index)) { + listNodes.add(index); + index = index.next; + } + return index; + } + } +}