LeetCode 142. 环形链表 II(逻辑环链表快慢双指针)
Posted 鲤鱼酒酒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 142. 环形链表 II(逻辑环链表快慢双指针)相关的知识,希望对你有一定的参考价值。
LeetCode 142. 环形链表 II
原题
思路
- 用一个哈希表存储已经访问过的结点,终止条件有两个:①如果发现这个节点再次被访问,则是入环的第一个节点,返回这个节点。②访问的指针指向null,则无环,返回null。
代码
/**
* Definition for singly-linked list.
* struct ListNode
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL)
* ;
*/
class Solution
public:
ListNode *detectCycle(ListNode *head)
map<ListNode*, bool> existed;
while (head != nullptr)
if (!existed[head])
existed[head] = true;
head = head->next;
else break;
return head;
;
运行截图
收获
- 看了题解,碰到有环的链表,应该将环和链表进行拆解,从head到入环前一个节点为a个节点,环为b个节点。同时这类题一般使用快慢双指针来做,这里面的逻辑关系有 快指针走过的步数f = 2* 慢指针走过的步数s。 当他们相遇的时候 f = s + nb ,所以此时 s = nb,而任何一个指针走到入环的第一个节点时的步数都为 a + n*b,所以slow指针此时再往前走a步,就能到达入环的第一个节点。这里可用head和slow同步走来实现。
/**
* Definition for singly-linked list.
* struct ListNode
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL)
* ;
*/
class Solution
public:
ListNode *detectCycle(ListNode *head)
ListNode *fast = head, *slow = head;
while (fast != nullptr)
slow = slow->next;
if (fast->next == nullptr) return nullptr;
fast = fast->next->next;
if (fast == slow)
while (head != slow)
slow = slow->next;
head = head->next;
return slow;
return fast;
;
leetcode 环形链表 II
找到环的起点需要做一些不同于快慢指针的处理,我们可以在快慢指针第一次相遇后,将其中一个指针再次指向头结点,并以相同的速度使两个指针再次向前推进,再次相遇时,就是对应的环起点。
public ListNode detectCycle(ListNode head) { ListNode fast=head; ListNode slow=head; while(fast!=null&&fast.next!=null) { fast=fast.next.next; slow=slow.next; if(fast==slow) break; } if(fast==null||fast.next==null) return null; fast=head; while(fast!=slow) { fast=fast.next; slow=slow.next; } return slow; }
以上是关于LeetCode 142. 环形链表 II(逻辑环链表快慢双指针)的主要内容,如果未能解决你的问题,请参考以下文章