求链表是否有环,以及环的长度 和入环节点

  • 判断链表是否有环,可以用快慢指针来实现
    快指针一次走两步,满指针一次走一步
    如果快指针为空或者其next节点为空,则表示链表没有环
    如果快慢指针相遇了,则表示链表有环

  • 在有环情况下,我们来找到其入环节点
    在这里插入图片描述
    解析:
    在这里插入图片描述

  • 计算环的长度

快慢指针第一次相遇后,快指针一次一步,慢指针不动,每走一步,计数一次,直到两者再次相遇,即为环的长度

public class ISCycle {
    private static class Node{
        int data;
        Node next;
        public Node(int data){
            this.data=data;
        }
    }

    /**
     * 判断单链表是否有环
     * @param head
     * @return
     */
    public static boolean isCycle(Node head){
        Node A=head;
        Node B=head;
        while (A!=null&&A.next!=null){
            A=A.next.next;
            B=B.next;
            if(A==B){
                return true;
            }
        }
        return false;
    }

    /**
     * 计算单链表环的长度
     * @param head
     * @return
     */
    public static int cycleLength(Node head){
        Node A=head;
        Node B=head;
        boolean flag=false;  //为true时证明有环,开始计数
        int cycleLength=0;
        while (A!=null&&A.next!=null){
            A=A.next.next;
            B=B.next;
            if(A==B){
                flag=true;
                break;
            }
        }
        if(flag==true){
            A=A.next;
            cycleLength++;  //有环的话,最小长度也是1
            while (A!=B){
                cycleLength++;
                A=A.next;
            }
        }
        return cycleLength;
    }

    /**
     * 求单链表环的入环节点
     * @param head
     * @return
     */
    public static Node getCycleNode(Node head){
        Node A=head;
        Node B=head;
        boolean hasCycle=false;  //有无环的标志
        Node cycleNode=null;   //入环节点
        while (A.next!=null&&A!=null){
            A=A.next.next;
            B=B.next;
            if(A==B){
                hasCycle=true;
                break;
            }
        }
        if(hasCycle==true){
            B=head;
            cycleNode=B;  //头节点就是入环节点的情况
            while (A!=B){
                A=A.next;
                B=B.next;
                if(A==B){
                    cycleNode=B;
                    break;
                }
            }
            return cycleNode;
        }
        return cycleNode;
    }

    public static void main(String[] args) {
        Node node1=new Node(5);
        Node node2=new Node(3);
        Node node3=new Node(8);
        Node node4=new Node(5);
        Node node5=new Node(6);
        Node node6=new Node(9);
        node1.next=node2;
        node2.next=node3;
        node3.next=node4;
        node4.next=node5;
        node5.next=node6;
        node6.next=node2;

        System.out.println(isCycle(node1));
        System.out.println(cycleLength(node1));
        System.out.println(getCycleNode(node1).data);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值