题目连接
示例
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。