原题
LeetCode 142. 环形链表 II
思路
用一个哈希表存储已经访问过的结点,终止条件有两个:①如果发现这个节点再次被访问,则是入环的第一个节点,返回这个节点。②访问的指针指向null,则无环,返回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 = n b,而任何一个指针走到入环的第一个节点时的步数都为 a + n*b,所以slow指针此时再往前走a步,就能到达入环的第一个节点。这里可用head和slow同步走来实现。
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;
}
} ;