题目连接
示例
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
解题思路
代码
// 返回环形链表的第一个交叉点public class leetcode142 {// 1。判断是否是环形链表 2。得到交点// 哈希表// 快慢指针public ListNode detectCycle1(ListNode head) {ListNode pos = head;Set<ListNode> visited = new HashSet<ListNode>();while (pos != null) {if (visited.contains(pos)) {return pos;} else {visited.add(pos);}pos = pos.next;}return null;}public ListNode detectCycle2(ListNode head) {if (head == null) return null;ListNode slow = head;ListNode fast = head;while (fast != null){slow = slow.next;if (fast.next!=null){fast = fast.next.next;}else {return null;}if (fast == slow){ListNode ptr = head;while (ptr != slow){ptr = ptr.next;slow = slow.next;}return ptr;}}return null;}}
这个代码比较清晰
:::info
- 定义快慢节点都在头节点处
- 循环。退出条件是
- 没有环形链表:fast == null || fast.next == null
- 有环形链表:slow == fast
当退出循环,并且程序还在运行时,即,出现环形链表,此时快慢双指针都在交点处
- 定义一个新节点在头节点处,为了节省空间,将上面的快指针重置到头节点处
- 循环。每次移动一个位置,当重置后的快指针移动到交点处时,慢指针已经移动了n-1圈,恰好相遇
时间复杂度 O(N):第二次相遇中,慢指针须走步数 a空间复杂度 O(1) :双指针使用常数大小的额外空间。 :::
public ListNode detectCycle(ListNode head) {ListNode fast = head, slow = head;while (true) {if (fast == null || fast.next == null) return null;fast = fast.next.next;slow = slow.next;if (fast == slow) break;}fast = head;while (slow != fast) {slow = slow.next;fast = fast.next;}return fast;}作者:jyd链接:https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-/来源:力扣(LeetCode)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
