Skip to content

Commit 91a1070

Browse files
committed
Linked List Cycle II 增加推理过程
1 parent 4aefe16 commit 91a1070

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

C++/LeetCodet题解(C++版).pdf

1.32 KB
Binary file not shown.

C++/chapLinearList.tex

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,8 +2025,7 @@ \subsubsection{递归版}
20252025
public:
20262026
ListNode *deleteDuplicates(ListNode *head) {
20272027
if (!head) return head;
2028-
ListNode dummy(head->val + 1); // 值只要跟head不同即可
2029-
dummy.next = head;
2028+
ListNode dummy{head->val + 1, head}; // 值只要跟head不同即可
20302029

20312030
recur(&dummy, head);
20322031
return dummy.next;
@@ -2246,8 +2245,7 @@ \subsubsection{代码}
22462245
class Solution {
22472246
public:
22482247
ListNode *removeNthFromEnd(ListNode *head, int n) {
2249-
ListNode dummy(0);
2250-
dummy.next = head;
2248+
ListNode dummy{-1, head};
22512249
ListNode *p = &dummy, *q = &dummy;
22522250

22532251
for (int i = 0; i < n; i++) // q先走n步
@@ -2513,7 +2511,7 @@ \subsubsection{描述}
25132511
\subsubsection{分析}
25142512
最容易想到的方法是,用一个哈希表\fn{unordered_map<int, bool> visited},记录每个元素是否被访问过,一旦出现某个元素被重复访问,说明存在环。空间复杂度$O(n)$,时间复杂度$O(N)$
25152513

2516-
最好的方法是时间复杂度O(n),空间复杂度O(1)的。设置两个指针,一个快一个慢,快的指针每次走两步,慢的指针每次走一步,如果快指针和慢指针相遇,则说明有环。参考\myurl{ http://leetcode.com/2010/09/detecting-loop-in-singly-linked-list.html}
2514+
最好的方法是时间复杂度$O(n)$,空间复杂度$O(1)$的。设置两个指针,一个快一个慢,快的指针每次走两步,慢的指针每次走一步,如果快指针和慢指针相遇,则说明有环。参考\myurl{ http://leetcode.com/2010/09/detecting-loop-in-singly-linked-list.html}
25172515

25182516

25192517
\subsubsection{代码}
@@ -2554,7 +2552,19 @@ \subsubsection{描述}
25542552

25552553

25562554
\subsubsection{分析}
2557-
\fn{slow}和\fn{fast}两个指针相遇后,另外设一个指针\fn{slow2},从\fn{head}开始,两个慢指针每次前进一步,它俩一定会在环的开始处相遇。
2555+
当fast与slow相遇时,slow肯定没有遍历完链表,而fast已经在环内循环了$n$圈($1 \leq n$)。假设slow走了$s$步,则fast走了$2s$步(fast步数还等于$s$加上在环上多转的$n$圈),设环长为$r$,则:
2556+
\begin{eqnarray}
2557+
2s &=& s + nr \nonumber \\
2558+
s &=& nr \nonumber
2559+
\end{eqnarray}
2560+
2561+
设整个链表长$L$,环入口点与相遇点距离为$a$,起点到环入口点的距离为$x$,则
2562+
\begin{eqnarray}
2563+
x + a &=& nr = (n – 1)r +r = (n-1)r + L - x \nonumber \\
2564+
x &=& (n-1)r + (L – x – a) \nonumber
2565+
\end{eqnarray}
2566+
2567+
$L – x – a$为相遇点到环入口点的距离,由此可知,从链表头到环入口点等于$n-1$圈内环+相遇点到环入口点,于是我们可以从\fn{head}开始另设一个指针\fn{slow2},两个慢指针每次前进一步,它俩一定会在环入口点相遇。
25582568

25592569

25602570
\subsubsection{代码}

0 commit comments

Comments
 (0)