zoukankan      html  css  js  c++  java
  • 求单链表中环的起点,原理详解

    1. 问题描述:

    链表结构如下,若链表中有环,返回环的起点,否则返回NULL

    1 struct ListNode
    2 {
    3     int val;
    4     ListNode *next;
    5     ListNode(const int val):val(val),next(NULL) {}
    6 };

     2. 解题代码:

    参考 LeetCode

     1 ListNode *detectCycle2(ListNode *head) {
     2     if(!head) return head;
     3     ListNode *stepA = head;// 每次走一步
     4     ListNode *stepB = head;// 每次走两步
     5     while (stepB && stepB->next) {
     6         stepA = stepA->next;
     7         stepB = stepB->next->next;
     8         if(stepA==stepB){
     9             ListNode *stepC = head;
    10             while (stepC != stepA) {
    11                 stepC = stepC->next;
    12                 stepA = stepA->next;
    13             }
    14             return stepC;
    15         }
    16     }
    17     return NULL;
    18 }

    3. 原理详解:

    (1)假设链表头到环起点的距离为S1,环的长度为S0;在环中相遇时stepA走的路程是SA,stepB走的路程是SB。则当SB>=SA>=S1时,以下结论成立:

    (SA-S1) mod S0 = (SB-S1) mod S0    <=>   (SB-SA) mod S0 = 0   <=>   SB-SA = n*S0   <=>   SA=n*S0;  (SB>=SA>=S1)

    a. 因为stepB的速度是stepA速度的两倍,所以SB=2SA;

    b. 所以 SB-SA=SA=nS0>=S1;

    c. 所以 n>=S1/S0,n为自然数

    d. 结论:只要满足条件 n>=S1/S0,则stepA和stepB就会在环上相遇;

    e. 第一次相遇时 n 的值为 S1/S0 向上取整,假设此时 n=n1,则 SA=n1*S0

    (2)stepA和stepB第一次在环上相遇后,让stepB停下,stepC从表头开始走,stepA从当前位置走,并且stepA和stepC一次只走一步。

     假设在环上相遇时stepA走的路程是SAA,stepC走的路程是SC,则当SC>=S1时,以下结论成立:

    (SC-S1) mod S0 = (SAA-S1) mod S0    <=>   (SAA-SC) mod S0 = 0     <=>   (SC+n1*S0-SC) mod S0 = 0     <=>   (n1*S0) mod S0 = 0;  (SC>=S1)

    a. 因为stepA和stepC的速度相同,所以等式SA A= SC+n1*S0成立;

    b. 所以(SAA-SC) mod S0 = 0     <=>   (SC+n1*S0-SC) mod S0 = 0     <=>   (n1*S0) mod S0 = 0

    c. 因为 (n1*S0) mod S0 = 0 恒成立,所以 stepA和stepC在环上相遇也恒成立,只要满足SC>=S1就行;

    d. stepA和stepC在环上第一次相遇时,SC=S1,此时stepC正好在环的起点。

  • 相关阅读:
    使用反射获取对象的步骤
    金融IT的算法要求
    Java编译与反编译命令记录
    常用搜索博客/网站
    Java核心-03 谈谈final、finally、 finalize有什么不同?
    Java核心-02 Exception和Error有什么区别?
    PHP函数技巧篇
    IO
    Markdown 简单使用教程
    FZu Problem 2233 ~APTX4869 (并查集 + sort)
  • 原文地址:https://www.cnblogs.com/woxinfeixiang2015/p/10143419.html
Copyright © 2011-2022 走看看