• LeetCode:Linked List Cycle II


    题目:判断单链表是否有环,如果有则找出环的起点。题目链接

    这是另一道题的扩展,利用快慢指针判断出是否有环后,还需要找出环的起点,分析如下:

    • 设链表长度为len(链表中非空next指针的个数,下面所说的长度均为非空next指针的个数),链表head到环的起点长度为a,环起点到快慢指针相遇点的长度为b,环的长度为r。
    • 假设到快慢指针相遇时,慢指针移动的长度为s,则快指针移动长度为2s,而快指针移动的长度还等于s加上在环上绕的k圈(k>=1),所以2s=s+kr ,即s = kr。
    • 由s = a + b 和 s = kr 可知 a + b = kr = (k-1)r + r; 而r = len - a,所以a + b = (k-1)r + len - a, 即 a = (k-1)r + len - a - blen - a - b是相遇点到环的起点的长度,由此可知,从链表头到环起点长度 = (k-1)环长度+从相遇点到环起点长度,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇点为环起点

    代码如下:

     1 /**
     2  * Definition for singly-linked list.
     3  * struct ListNode {
     4  *     int val;
     5  *     ListNode *next;
     6  *     ListNode(int x) : val(x), next(NULL) {}
     7  * };
     8  */
     9 class Solution {
    10 public:
    11     ListNode *detectCycle(ListNode *head) {
    12         // IMPORTANT: Please reset any member data you declared, as
    13         // the same Solution instance will be reused for each test case.
    14         if(head == NULL || head->next == NULL)return NULL;
    15         ListNode *fast = head, *low = head;
    16         while(fast != NULL && fast->next != NULL)
    17         {
    18             low  = low->next;
    19             fast = fast->next->next;
    20             if(low == fast)break;
    21         }
    22         if(low == fast)
    23         {//寻找环的起点
    24             fast = head;
    25             while(fast != low)
    26             {
    27                 fast = fast->next;
    28                 low = low->next;
    29             }
    30             return low;
    31         }
    32         else return NULL;
    33     }
    34 };

    【版权声明】转载请注明出处:

  • 相关阅读:
    P4009 汽车加油行驶问题
    P2761 软件补丁问题
    P1251 餐巾计划问题
    P2766 最长不下降子序列问题
    P4011 孤岛营救问题
    P2765 魔术球问题
    P2770 航空路线问题
    P2762 太空飞行计划问题
    P2764 最小路径覆盖问题
    P3355 骑士共存问题
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3416702.html
Copyright © 2020-2023  润新知