zoukankan      html  css  js  c++  java
  • 【链表】怎么判断链表有环,怎么找环节点

    思路(证明有环):

    定义快慢指针fast和slow,fast每次前进两步,slow每次前进一步;

    当fast和slow在到达链尾之前相遇的话,就证明有环(类似于在操场上跑步跑的慢的被快的套圈但总会遇到);

    思路(找环结点):

    fast和slow相遇之后,fast不动,slow回到最初的起点,然后一步一步的等在再次相遇,这时候相遇地点就是环结点

    证明如下,是个数学问题。。。

    设一环的距离是R,k代表环数

    slow走过的距离:AB+BC

    fast走过的距离:AB+BC+k*R

    因为slow每次一步,fast每次两步,所以距离有两倍关系

    2(AB+BC)=AB+BC+k*R

    AB+BC=(k-1)*R+BC+CB

    AB=(k-1)*R+CB

    所以结论就是fast从C->B加k圈停在B的时候,slow正好从A->B到达B

     1 #include <iostream>
     2 using namespace std;
     3 
     4 typedef struct ListNode* List;
     5 struct ListNode {
     6     int data;
     7     List next;
     8 };
     9 
    10 List judge(List L) {
    11     if (L == NULL || L->next == NULL)
    12         return NULL;
    13     List fast = L;//定义快指针
    14     List slow = L;//定义慢指针
    15     while (fast->next->next != NULL &&fast->next!=NULL) {
    16         fast = fast->next->next;
    17         slow = slow->next;
    18         //如果指针相遇跳出循环
    19         if (fast == slow)
    20             break;
    21     }
    22     //如果到头也没有找到证明没有环
    23     if (fast->next == NULL || fast->next->next == NULL)
    24         return NULL;
    25 
    26     //此时fast记录相遇点,slow回到头指针
    27     slow = L;
    28     while (fast != slow) {
    29         fast = fast->next;
    30         slow = slow->next;
    31     }
    32     //再次相遇的结点就是环结点
    33     return slow;
    34 }

    思路参考https://segmentfault.com/a/1190000015308120

  • 相关阅读:
    http数据返回值
    刷新 返回
    微信平台上遇到的bug
    iscroll修改
    iscroll
    a标签的herf和click事件
    ios9+xcode7 适配笔记
    xsd、wsdl生成C#类的命令行工具使用方法
    xcode更新,想想也是醉了
    关于#define预处理指令的一个问题
  • 原文地址:https://www.cnblogs.com/PennyXia/p/12653090.html
Copyright © 2011-2022 走看看