数据结构--java语言实现返回链表中环的入口结点,若无环,则返回null

博客围绕找出链表环的入口结点问题展开。先给出题目,即若链表含环找出环入口结点,否则输出null。接着阐述解题思路,通过定义快慢引用,分析相遇情况得出规律。最后提及会进行代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1 题目描述

2 解题思路

3 代码实现


1 题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

2 解题思路

首先我们不难想到,遍历一遍单链表,若某一结点的next指向null,则说明该单链表无环,返回null;若有环,我们定义两个引用fast和slow,让fast每次走两步,slow每次走一步,它俩肯定会在某个结点处相遇,那么问题来了,我们如何求得这个结点呢?其实不难,画个图分析一下就出来了:

相遇时,fast经过的节点个数时slow的2倍(与走了几圈无关~),此时我们假设链表总的结点数为n,头结点到入环结点的结点个数是x,入环节点到相遇结点的结点数是y,则我们不难得出:2(x+y) = n+y -> x+x+y+y = n+y -> x+x+y = n+y;即相遇结点后的部分结点总数为x,那么此时我们将slow结点置为头结点slow和fast走x步,就可以到达相遇的结点处啦~如下图所示:

3 代码实现

public Node ExceCycle(){
        Node fast = this.head;
        Node slow = this.head;
        while (fast != null&&fast.next != null){
            //fast走两步,slow走一步
            fast = fast.next.next;
            slow = slow.next;
            //若有环,退出循环
            if (fast == slow){
                break;
            }
        }
        //当上面while条件不满足时,即该链表没有换环
        if (fast == null&&fast.next == null){
            return null;
        }
        //将slow置为头结点
        slow = this.head;
        while (fast != slow){
            //fast走一步,slow走一步,若相遇,则退出循环
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }

 

在 C++ 中创建一个链表并检测的长度通常需要使用快慢指针(Floyd's Cycle Detection Algorithm 或者也称为龟兔赛跑算法)。以下是实现的基本步骤: 1. 初始化两个指针 `slow` 和 `fast`,都指向链表的头节。 2. `slow` 指针每次移动一步,而 `fast` 指针每次移动两步。 3. 如果链表中存在,那么最终 `fast` 指针会追上 `slow` 指针;如果没有,`fast` 指针将会先到达链表的末尾(null)。 4. 当它们相遇时,说明找到了。此时,你可以设置一个新的指针 `pointer = slow`,然后同时移动 `slow` 和 `pointer`,它们每次各自向前移动一步,直到再次相遇。这次相遇的位置就是入口。 5. 计算的长度:从入口开始,将 `slow` 指针和 `pointer` 指针一起向后移动,数出它们相隔的节数,这就是的长度。如果 `slow` 没有超过 `pointer`,说明链表中不存在,直接返回 0。 ```cpp class ListNode { public: int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; ListNode* detectCycle(ListNode* head) { if (head == nullptr || head->next == nullptr) return nullptr; // 检查是否为空 ListNode* slow = head; ListNode* fast = head; while (fast != nullptr && fast->next != nullptr) { slow = slow->next; fast = fast->next->next; if (slow == fast) { // 找到 ListNode* pointer = slow; while (slow != pointer->next) { slow = slow->next; pointer = pointer->next; } return slow; // 返回入口 } } return nullptr; // 无情况 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值