力扣刷题记录12.1-----142. 环形链表 II


一、题目

在这里插入图片描述
在这里插入图片描述

二、代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
    
    /*
    思路:(1)快慢指针法判断是否有环    快的走两步 慢的走一步 步数差别为1 相当于追赶,一定会在环中间相遇
         (2)  x为环起始节点   y为相遇节点  z为剩余环长度 
              由快慢属性可知  2(x+y)=x+y+n(y+z)
                              x=n(y+z)-y     负数不如正数,多一圈少一圈一样
                              x=(n-1)(y+z)+Z     n=1时,从源节点出发和相遇节点出发,相交为环入口
                                                 n>1时,从源节点出发和相遇节点出发,相交为环入口(从相遇节点出发的走了n圈)
    */

     ///统一链表格式
    ListNode* dummyhead = new ListNode(0);  //设置虚假的头结点 为了使得单节点和多节点情况统一 
    dummyhead->next = head;

    ListNode* fast_node = new ListNode(0);  
    fast_node=dummyhead;

    ListNode* low_node = new ListNode(0); 
    low_node=dummyhead;

    ListNode* begin_source = new ListNode(0);  
    begin_source=dummyhead;

    ListNode* begin_meet = new ListNode(0);  

    ListNode* return_node = new ListNode(0);  

    if(fast_node->next==nullptr||fast_node->next->next==nullptr) return nullptr;//如果节点格数为0或者1  返回nullptr
    else
    {
      fast_node=fast_node->next->next;
      low_node=low_node->next;
      while(fast_node!=low_node)  //在循环中,如果是有环的节点 一定能够相遇 如果出现了nullptr 说明一定无环
      {
        if(fast_node->next==nullptr||fast_node->next->next==nullptr) return nullptr;
        else
        {
          fast_node=fast_node->next->next;
          low_node=low_node->next;
        }
      }
      //如果函数没有直接返回走到了这一步  说明快和慢相遇在了x+y处,此时新建节点开始跑,会相遇在环入口处
      begin_meet=fast_node;
      while(begin_meet!=begin_source)
      {
        begin_source=begin_source->next;
        begin_meet=begin_meet->next;
      }

      //退出时的节点即为所求
       return_node=begin_meet;
    }
    

    return return_node; 
    }
};

三、运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@白圭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值