{"id":641,"date":"2025-07-15T12:46:09","date_gmt":"2025-07-15T07:16:09","guid":{"rendered":"https:\/\/codeanddebug.in\/blog\/?p=641"},"modified":"2025-07-15T12:46:10","modified_gmt":"2025-07-15T07:16:10","slug":"linked-list-cycle-ii-leetcode-142","status":"publish","type":"post","link":"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/","title":{"rendered":"Linked List Cycle II | Leetcode 142 | Complete Guide with 2 Different Solutions"},"content":{"rendered":"\n<p>Given the&nbsp;<code>head<\/code>&nbsp;of a linked list, return&nbsp;<em>the node where the cycle begins. If there is no cycle, return&nbsp;<\/em><code>null<\/code>.<\/p>\n\n\n\n<p>Here&#8217;s the [<strong><a href=\"https:\/\/leetcode.com\/problems\/linked-list-cycle-ii\/description\/\" target=\"_blank\" rel=\"noreferrer noopener\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-purple-color\"><span style=\"text-decoration: underline;\">Problem Link<\/span><\/mark><\/a><\/strong>] to begin with.<\/p>\n\n\n\n<p>There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the&nbsp;<code>next<\/code>&nbsp;pointer. Internally,&nbsp;<code>pos<\/code>&nbsp;is used to denote the index of the node that tail&#8217;s&nbsp;<code>next<\/code>&nbsp;pointer is connected to (<strong>0-indexed<\/strong>). It is&nbsp;<code>-1<\/code>&nbsp;if there is no cycle.&nbsp;<strong>Note that<\/strong>&nbsp;<code>pos<\/code>&nbsp;<strong>is not passed as a parameter<\/strong>.<\/p>\n\n\n\n<p><strong>Do not modify<\/strong>&nbsp;the linked list.<\/p>\n\n\n\n<p><strong>Example 1:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/assets.leetcode.com\/uploads\/2018\/12\/07\/circularlinkedlist.png\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Input:<\/strong> head = [3,2,0,-4], pos = 1<br><strong>Output:<\/strong> tail connects to node index 1<br><strong>Explanation:<\/strong> There is a cycle in the linked list, where tail connects to the second node.<\/pre>\n\n\n\n<p><strong>Example 2:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/assets.leetcode.com\/uploads\/2018\/12\/07\/circularlinkedlist_test2.png\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Input:<\/strong> head = [1,2], pos = 0<br><strong>Output:<\/strong> tail connects to node index 0<br><strong>Explanation:<\/strong> There is a cycle in the linked list, where tail connects to the first node.<\/pre>\n\n\n\n<p><strong>Example 3:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/assets.leetcode.com\/uploads\/2018\/12\/07\/circularlinkedlist_test3.png\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>Input:<\/strong> head = [1], pos = -1<br><strong>Output:<\/strong> no cycle<br><strong>Explanation:<\/strong> There is no cycle in the linked list.<\/pre>\n\n\n\n<p><strong>Constraints:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The number of the nodes in the list is in the range\u00a0<code>[0, 10<sup>4<\/sup>]<\/code>.<\/li>\n\n\n\n<li><code>-10<sup>5<\/sup> &lt;= Node.val &lt;= 10<sup>5<\/sup><\/code><\/li>\n\n\n\n<li><code>pos<\/code>\u00a0is\u00a0<code>-1<\/code>\u00a0or a\u00a0<strong>valid index<\/strong>\u00a0in the linked-list.<\/li>\n<\/ul>\n\n\n\n<p><strong>Follow up:<\/strong>&nbsp;Can you solve it using&nbsp;<code>O(1)<\/code>&nbsp;(i.e. constant) memory?<\/p>\n\n\n<div style=\"max-width: -moz-fit-content; \" class=\"wp-block-ub-table-of-contents-block ub_table-of-contents ub_table-of-contents-collapsed\" id=\"ub_table-of-contents-88939b7e-ba2f-4af1-a6e8-ad4f1030c6e3\" data-linktodivider=\"false\" data-showtext=\"show\" data-hidetext=\"hide\" data-scrolltype=\"auto\" data-enablesmoothscroll=\"true\" data-initiallyhideonmobile=\"true\" data-initiallyshow=\"false\"><div class=\"ub_table-of-contents-header-container\" style=\"\">\n\t\t\t<div class=\"ub_table-of-contents-header\" style=\"text-align: left; \">\n\t\t\t\t<div class=\"ub_table-of-contents-title\">Contents:<\/div>\n\t\t\t\t<div class=\"ub_table-of-contents-header-toggle\">\n\t\t\t<div class=\"ub_table-of-contents-toggle\" style=\"\">\n\t\t\t\u00a0[<a class=\"ub_table-of-contents-toggle-link\" href=\"#\" style=\"\">show<\/a>]\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t<\/div>\n\t\t<\/div><div class=\"ub_table-of-contents-extra-container\" style=\"\">\n\t\t\t<div class=\"ub_table-of-contents-container ub_table-of-contents-1-column ub-hide\">\n\t\t\t\t<ul style=\"\"><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#0-solution-1-brute-force-approach-using-set\" style=\"\">Solution 1: Brute Force Approach (Using Set)<\/a><ul><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#1-intuition\" style=\"\">Intuition<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#2-detailed-approach\" style=\"\">Detailed Approach<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#3-code\" style=\"\">Code<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#4-code-explanation\" style=\"\">Code Explanation<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#5-dry-run\" style=\"\">Dry Run<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#6-time-and-space-complexity\" style=\"\">Time and Space Complexity<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#7-simplifying-it\" style=\"\">Simplifying It<\/a><\/li><\/ul><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#8-solution-2-optimal-approach-floyds-algorithm-cycle-start-detection\" style=\"\">Solution 2: Optimal Approach (Floyd&#8217;s Algorithm + Cycle Start Detection)<\/a><ul><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#9-intuition\" style=\"\">Intuition<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#10-detailed-approach\" style=\"\">Detailed Approach<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#11-code\" style=\"\">Code<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#12-code-explanation\" style=\"\">Code Explanation<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#13-dry-run\" style=\"\">Dry Run<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#14-time-and-space-complexity\" style=\"\">Time and Space Complexity<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#15-simplifying-it\" style=\"\">Simplifying It<\/a><\/li><\/ul><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#16-why-does-the-optimal-solution-work\" style=\"\">Why Does the Optimal Solution Work?<\/a><\/li><li style=\"\"><a href=\"https:\/\/codeanddebug.in\/blog\/linked-list-cycle-ii-leetcode-142\/#17-summary\" style=\"\">Summary<\/a><\/li><\/ul>\n\t\t\t<\/div>\n\t\t<\/div><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"0-solution-1-brute-force-approach-using-set\">Solution 1: Brute Force Approach (Using Set)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"1-intuition\">Intuition<\/h3>\n\n\n\n<p>This is similar to the previous cycle detection problem, but instead of just checking if there&#8217;s a cycle, we need to find exactly where the cycle starts. Think of it like walking through a maze while dropping breadcrumbs. The moment you find a breadcrumb you&#8217;ve already dropped, that&#8217;s exactly where you started going in circles!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"2-detailed-approach\">Detailed Approach<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Create a Tracking System<\/strong>: Use a set to remember all the nodes we&#8217;ve visited<\/li>\n\n\n\n<li><strong>Walk Through the List<\/strong>: Move through each node one by one<\/li>\n\n\n\n<li><strong>Check Before Adding<\/strong>: At each node, check if we&#8217;ve seen it before<\/li>\n\n\n\n<li><strong>Found the Cycle Start<\/strong>: If we find a node we&#8217;ve already visited, that&#8217;s where the cycle begins<\/li>\n\n\n\n<li><strong>Reached the End<\/strong>: If we reach the end (None), there&#8217;s no cycle<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"3-code\">Code<\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"class Solution:\n    def detectCycle(self, head: Optional[ListNode]) -&gt; Optional[ListNode]:\n        my_set = set()           # Set to store visited nodes\n        temp = head              # Current node we're examining\n        \n        while temp is not None:\n            if temp in my_set:   # Check if we've seen this node before\n                return temp      # This is where the cycle starts!\n            my_set.add(temp)     # Remember this node for future\n            temp = temp.next     # Move to the next node\n        \n        return None             # Reached end, no cycle found\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Solution<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">detectCycle<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">self<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">head<\/span><span style=\"color: #D4D4D4\">: Optional[ListNode]) -&gt; Optional[ListNode]:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        my_set = <\/span><span style=\"color: #4EC9B0\">set<\/span><span style=\"color: #D4D4D4\">()           <\/span><span style=\"color: #6A9955\"># Set to store visited nodes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        temp = head              <\/span><span style=\"color: #6A9955\"># Current node we&#39;re examining<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">while<\/span><span style=\"color: #D4D4D4\"> temp <\/span><span style=\"color: #569CD6\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">None<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> temp <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> my_set:   <\/span><span style=\"color: #6A9955\"># Check if we&#39;ve seen this node before<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> temp      <\/span><span style=\"color: #6A9955\"># This is where the cycle starts!<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            my_set.add(temp)     <\/span><span style=\"color: #6A9955\"># Remember this node for future<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            temp = temp.next     <\/span><span style=\"color: #6A9955\"># Move to the next node<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">None<\/span><span style=\"color: #D4D4D4\">             <\/span><span style=\"color: #6A9955\"># Reached end, no cycle found<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#1E1E1E;color:#c7c7c7;font-size:12px;line-height:1;position:relative\">Python<\/span><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"4-code-explanation\">Code Explanation<\/h3>\n\n\n\n<p>We start from the head and visit each node one by one. Before moving to the next node, we check if the current node is already in our set. If it is, we&#8217;ve found the exact node where the cycle begins because this is the first time we&#8217;re visiting a node for the second time. If it&#8217;s not in the set, we add it and continue. If we reach the end of the list (temp becomes None), it means there&#8217;s no cycle.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"5-dry-run\">Dry Run<\/h3>\n\n\n\n<p>Let&#8217;s trace through a list with cycle:&nbsp;<code>1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 2<\/code>&nbsp;(4 points back to 2)<\/p>\n\n\n\n<p><strong>Step 1:<\/strong>&nbsp;temp=1, my_set={}, add 1: my_set={1}<br><strong>Step 2:<\/strong>&nbsp;temp=2, my_set={1}, add 2: my_set={1, 2}<br><strong>Step 3:<\/strong>&nbsp;temp=3, my_set={1, 2}, add 3: my_set={1, 2, 3}<br><strong>Step 4:<\/strong>&nbsp;temp=4, my_set={1, 2, 3}, add 4: my_set={1, 2, 3, 4}<br><strong>Step 5:<\/strong>&nbsp;temp=2, my_set={1, 2, 3, 4}, 2 is already in set \u2192 return node 2<\/p>\n\n\n\n<p><strong>Result:<\/strong>&nbsp;Cycle starts at node 2!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"6-time-and-space-complexity\">Time and Space Complexity<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Time Complexity:<\/strong>\u00a0O(n) &#8211; We visit each node at most once before detecting the cycle start<\/li>\n\n\n\n<li><strong>Space Complexity:<\/strong>\u00a0O(n) &#8211; In worst case, we store all nodes in the set<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"7-simplifying-it\">Simplifying It<\/h3>\n\n\n\n<p>This approach is straightforward &#8211; keep a record of everywhere you&#8217;ve been, and the first place you visit twice is where the cycle begins. However, it uses extra memory to store all the visited nodes.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"8-solution-2-optimal-approach-floyds-algorithm-cycle-start-detection\">Solution 2: Optimal Approach (Floyd&#8217;s Algorithm + Cycle Start Detection)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"9-intuition\">Intuition<\/h3>\n\n\n\n<p>This is like a two-phase detective story! First, we use the &#8220;tortoise and hare&#8221; method to confirm there&#8217;s a cycle. Then, we use a clever mathematical trick: when the two pointers meet inside the cycle, we reset one pointer to the head and move both pointers one step at a time. They will meet exactly at the cycle&#8217;s starting point!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"10-detailed-approach\">Detailed Approach<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Phase 1 &#8211; Detect Cycle<\/strong>: Use two pointers (slow and fast) to detect if a cycle exists<\/li>\n\n\n\n<li><strong>Phase 2 &#8211; Find Cycle Start<\/strong>: Once cycle is detected, reset slow pointer to head<\/li>\n\n\n\n<li><strong>Move Both Pointers<\/strong>: Move both pointers one step at a time until they meet<\/li>\n\n\n\n<li><strong>Meeting Point<\/strong>: The point where they meet is the start of the cycle<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"11-code\">Code<\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"class Solution:\n    def detectCycle(self, head: Optional[ListNode]) -&gt; Optional[ListNode]:\n        slow = head          # Slow pointer (tortoise)\n        fast = head          # Fast pointer (hare)\n        \n        # Phase 1: Detect if cycle exists\n        while fast and fast.next:\n            slow = slow.next      # Move slow pointer 1 step\n            fast = fast.next.next # Move fast pointer 2 steps\n            \n            if slow == fast:      # Cycle detected!\n                # Phase 2: Find cycle start\n                slow = head       # Reset slow to head\n                while slow != fast:\n                    slow = slow.next  # Move both pointers 1 step each\n                    fast = fast.next\n                return slow       # They meet at cycle start\n        \n        return None              # No cycle found\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">class<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Solution<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">detectCycle<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">self<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">head<\/span><span style=\"color: #D4D4D4\">: Optional[ListNode]) -&gt; Optional[ListNode]:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        slow = head          <\/span><span style=\"color: #6A9955\"># Slow pointer (tortoise)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        fast = head          <\/span><span style=\"color: #6A9955\"># Fast pointer (hare)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\"># Phase 1: Detect if cycle exists<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">while<\/span><span style=\"color: #D4D4D4\"> fast <\/span><span style=\"color: #569CD6\">and<\/span><span style=\"color: #D4D4D4\"> fast.next:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            slow = slow.next      <\/span><span style=\"color: #6A9955\"># Move slow pointer 1 step<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            fast = fast.next.next <\/span><span style=\"color: #6A9955\"># Move fast pointer 2 steps<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> slow == fast:      <\/span><span style=\"color: #6A9955\"># Cycle detected!<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #6A9955\"># Phase 2: Find cycle start<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                slow = head       <\/span><span style=\"color: #6A9955\"># Reset slow to head<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">while<\/span><span style=\"color: #D4D4D4\"> slow != fast:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    slow = slow.next  <\/span><span style=\"color: #6A9955\"># Move both pointers 1 step each<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    fast = fast.next<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> slow       <\/span><span style=\"color: #6A9955\"># They meet at cycle start<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">None<\/span><span style=\"color: #D4D4D4\">              <\/span><span style=\"color: #6A9955\"># No cycle found<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#1E1E1E;color:#c7c7c7;font-size:12px;line-height:1;position:relative\">Python<\/span><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"12-code-explanation\">Code Explanation<\/h3>\n\n\n\n<p>This solution works in two phases. In Phase 1, we use the classic two-pointer technique to detect if a cycle exists. Once we confirm there&#8217;s a cycle (when slow equals fast), we enter Phase 2. We reset the slow pointer to the head and then move both pointers one step at a time. Due to the mathematical properties of the cycle, they will meet exactly at the node where the cycle begins.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"13-dry-run\">Dry Run<\/h3>\n\n\n\n<p>Let&#8217;s trace through:&nbsp;<code>1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 2<\/code>&nbsp;(4 points back to 2)<\/p>\n\n\n\n<p><strong>Phase 1 &#8211; Cycle Detection:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Initial: slow=1, fast=1<\/li>\n\n\n\n<li>Step 1: slow=2, fast=3<\/li>\n\n\n\n<li>Step 2: slow=3, fast=2 (cycle)<\/li>\n\n\n\n<li>Step 3: slow=4, fast=4<\/li>\n\n\n\n<li>Cycle detected! slow == fast at node 4<\/li>\n<\/ul>\n\n\n\n<p><strong>Phase 2 &#8211; Find Cycle Start:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Reset slow to head: slow=1, fast=4<\/li>\n\n\n\n<li>Step 1: slow=2, fast=2<\/li>\n\n\n\n<li>They meet at node 2!<\/li>\n<\/ul>\n\n\n\n<p><strong>Result:<\/strong>&nbsp;Cycle starts at node 2<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"14-time-and-space-complexity\">Time and Space Complexity<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Time Complexity:<\/strong>\u00a0O(n) &#8211; We traverse the list at most twice<\/li>\n\n\n\n<li><strong>Space Complexity:<\/strong>\u00a0O(1) &#8211; We only use two pointer variables<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"15-simplifying-it\">Simplifying It<\/h3>\n\n\n\n<p>The magic here is in the math! When the two pointers meet during cycle detection, the distance from the head to the cycle start equals the distance from the meeting point to the cycle start (when moving forward in the cycle). This is why resetting one pointer to head and moving both at the same speed makes them meet at the cycle start.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"16-why-does-the-optimal-solution-work\">Why Does the Optimal Solution Work?<\/h2>\n\n\n\n<p>Let&#8217;s break down the math in simple terms:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>L1<\/strong>\u00a0= Distance from head to cycle start<\/li>\n\n\n\n<li><strong>L2<\/strong>\u00a0= Distance from cycle start to meeting point<\/li>\n\n\n\n<li><strong>C<\/strong>\u00a0= Cycle length<\/li>\n<\/ul>\n\n\n\n<p>When fast and slow meet:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Slow traveled: L1 + L2<\/li>\n\n\n\n<li>Fast traveled: L1 + L2 + C (one extra cycle)<\/li>\n\n\n\n<li>Since fast moves twice as fast: 2(L1 + L2) = L1 + L2 + C<\/li>\n\n\n\n<li>Simplifying: L1 + L2 = C, so L1 = C &#8211; L2<\/li>\n<\/ul>\n\n\n\n<p>This means the distance from head to cycle start (L1) equals the distance from meeting point to cycle start (C &#8211; L2). That&#8217;s why they meet at the cycle start!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"17-summary\">Summary<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Approach<\/th><th>Time<\/th><th>Space<\/th><th>Difficulty<\/th><th>Best For<\/th><\/tr><\/thead><tbody><tr><td>Brute Force (Set)<\/td><td>O(n)<\/td><td>O(n)<\/td><td>Easy<\/td><td>Learning the concept<\/td><\/tr><tr><td>Two Pointers (Floyd&#8217;s)<\/td><td>O(n)<\/td><td>O(1)<\/td><td>Hard<\/td><td>Production code<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The&nbsp;<strong>two pointers approach<\/strong>&nbsp;is generally preferred because it uses constant space while maintaining the same time efficiency. However, the brute force approach is more intuitive and easier to understand when you&#8217;re first learning about cycle detection.<\/p>\n\n\n\n<p>The optimal solution is a beautiful example of how mathematical insights can lead to elegant algorithms. While it&#8217;s trickier to understand initially, mastering this technique will help you solve many advanced linked list problems!<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-16018d1d wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/codeanddebug.in\/course\/zero-to-hero-python-dsa\" target=\"_blank\" rel=\"noreferrer noopener\">Join our Advance DSA COURSE<\/a><\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><em>For any changes to the article, kindly email at <a href=\"mailto:code@codeanddebug.in\" target=\"_blank\" rel=\"noreferrer noopener\">code@codeanddebug.in<\/a> or contact us at <a href=\"tel:+91-9712928220\" target=\"_blank\" rel=\"noreferrer noopener\">+91-9712928220<\/a>.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Given the&nbsp;head&nbsp;of a linked list, return&nbsp;the node where the cycle begins. If there is no cycle, return&nbsp;null. Here&#8217;s the [Problem Link] to begin with. There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the&nbsp;next&nbsp;pointer. Internally,&nbsp;pos&nbsp;is used to denote the index<\/p>\n","protected":false},"author":1,"featured_media":642,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,6],"tags":[19,29],"class_list":{"0":"post-641","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-data-structures-and-algorithm","8":"category-intermediate","9":"tag-medium","10":"tag-singly-linked-list"},"featured_image_src":"https:\/\/codeanddebug.in\/blog\/wp-content\/uploads\/2025\/07\/linked-list-cycle-II-featured-image.png","author_info":{"display_name":"codeanddebug","author_link":"https:\/\/codeanddebug.in\/blog\/author\/codeanddebug\/"},"_links":{"self":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts\/641","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/comments?post=641"}],"version-history":[{"count":1,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts\/641\/revisions"}],"predecessor-version":[{"id":643,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/posts\/641\/revisions\/643"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/media\/642"}],"wp:attachment":[{"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/media?parent=641"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/categories?post=641"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codeanddebug.in\/blog\/wp-json\/wp\/v2\/tags?post=641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}