java单链表关于链表是否有环以及寻找环入口

这篇博客主要介绍了如何使用Java判断单链表是否带有环以及如何寻找带环链表的环入口。通过设置快慢指针,当快指针和慢指针相遇时,表明链表存在环。若链表无环,快指针会先到达null。对于寻找环的入口,当快慢指针相遇后,慢指针回溯到头节点,再同步行走,两者再次相遇的位置即为环的入口。

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

   一:判断链表是否为带环链表     

首先如何判断链表是否有环,这个时候首先需要知道链表是否为空,如果不为空,则继续判断。

       思路:首先定义两个变量,一个fast,一个slow,让fast 每次走两步,slow每次走一步,当fast和slow相遇时,即是该链表存在环结构。如果该链表为无环结构,则当遍历完这个链表时也不会相遇。即是返回false。

        

        判断条件:  (fast != null      &&     fast.next != null)

        如果存在环形结构则如下图所示:

        

                  初始值都指向头结点                                                                    走第一步

 

                   

                          走第二步                                                                               走第三步

       当走到第三步的时候,发现fast和slow相等,所以返回值为true。该单链表为有环结构。

 

        无环结构的判断:

         判断条件:  fast != null      &&     fast.next != null

        如果不存在环形结构则如下图所示:

               初始值两值都指向头结点                                                              走第一步

 

                  走第三步

 

        当走到第三步的时候,发现fast.next为空,所以结束判断。如果当循环结束之后还没有返回,则是返回false。

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                return true;
            }
        }
        return false;
    
    }
}

 

二:寻找带环链表的环入口

如果链表为有环结构,则需要寻找到这个的入口,如何寻找到这个入口,可以看看下图讲解。

 

如图步骤:

 

          第一步,fast和slow都指向头结点                               第二步,fast走两步,slow走一步

 

 

                   第三步                                                      第四步,fast和slow相遇,链表有环,此时将slow移回头结点位置

 

        

               移回头结点之后的图                                                       接着走,此时让fast和slow没都走一步

 

      接下来就是一直同步走,直到再次相遇                                          再次相遇,此时slow和fast所指向的位置即是环的入口

 

寻找环的入口的代码:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                break;
            }
        }        
        if(fast == null || fast.next == null){
            return null;
        }
        
            slow = head;
            while(fast != slow){
                slow = slow.next;
                fast = fast.next;    
            }
        return slow;
        
    }
    
}

 

### Java单链表检测算法 在Java中,判断单链表是否存在可以通过快慢指针法实现。这种方法基于两个指针以不同速度遍历链表的原理。如果链表存在,则两个指针会在某一时刻相遇;否则,其中一个指针会先到达链表末尾[^1]。 以下是具体实现代码: ```java public class ListNode { int val; ListNode next; ListNode(int val) { this.val = val; this.next = null; } } public class Solution { public boolean hasCycle(ListNode head) { if (head == null || head.next == null) { return false; } ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null) { slow = slow.next; // 慢指针每次移动一步 fast = fast.next.next; // 快指针每次移动两步 if (slow == fast) { // 如果快慢指针相遇,则存在 return true; } } return false; // 如果快指针到达链表末尾,则不存在 } } ``` #### 算法分析 - **时间复杂度**:O(n),其中n为链表中的节点数。快慢指针最多遍历整个链表一次[^2]。 - **空间复杂度**:O(1),仅使用了两个额外的指针变量(`slow`和`fast`)[^3]。 #### 入口点检测 除了判断链表是否存在外,还可以进一步找到入口点。以下是实现代码: ```java public ListNode detectCycle(ListNode head) { ListNode slow = head, fast = head; boolean hasCycle = false; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) { hasCycle = true; break; } } if (!hasCycle) { return null; // 无 } slow = head; while (slow != fast) { slow = slow.next; fast = fast.next; } return slow; // 返回入口点 } ``` 此方法通过将慢指针重新指向头节点,并与快指针以相同速度前进,最终两者会在入口点相遇。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值