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

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

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

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

        

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

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

        

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

                   

                          走第二步                                                                               走第三步

扫描二维码关注公众号,回复: 6197385 查看本文章

       当走到第三步的时候,发现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;
        
    }
    
}

猜你喜欢

转载自blog.csdn.net/lin140611/article/details/89461362