Python 每日一记234>>>Java快慢指针判断链表是否为环形、寻找环形入口

本来想学习一下找环的入口的数学知识,结果实在是想不通,还是先放一放吧,直接上代码了:

package mypackage;

//测试
public class MyJava {

    //节点类
    private static class Node<T> {
        T data;
        Node next;

        //构造方法
        public Node(T data, Node next) {
            this.data = data;
            this.next = next;
        }
    }
    //    判断是否是环形链表
    public static boolean isCircle(Node node){
//        定义快慢指针
        Node fast=node;
        Node slow=node;
//        快指针不是null,且下一个节点也不是null的情况下
//        让快指针每次走两步,慢指针每次走一步
//        如果快慢指针能相遇,那么就证明链表是环形的
        while((fast!=null)&&(fast.next!=null)){
//            两个next就是模拟两步
            fast=fast.next.next;
            slow=slow.next;
            if (fast.equals(slow)){
//                return直接结束isCircle方法,自然就具有退出循环的作用
                System.out.println("快慢指针相遇点:"+fast.data);
                return true;
            }
        }
//        跳出循环表示有结束节点,不是环形的
        return false;
    }

    //找出环的入口
//    先定义一个临时Node指针,当判断是环形链表时,此时快慢指针相遇,
//    这个时候将temp指针赋值为第一个节点,就是entrance方法传入的参数,且让temp以和慢指针一样的速度移动
//    当慢指针和temp相遇时,共同指向的节点就是环的入口
    public static Integer entrance(Node node){
//        定义快慢指针
        Node fast=node;
        Node slow=node;
        Node temp=null;
//        快指针不是null,且下一个节点也不是null的情况下
//        让快指针每次走两步,慢指针每次走一步
        while((fast!=null)&&(fast.next!=null)){
//            两个next就是模拟两步
            fast=fast.next.next;
            slow=slow.next;
            if (fast.equals(slow)){
//                这时链表已经判断为环形的
//                temp赋值完后,continue直接进入下一次循环,跳过之后的代码
                temp=node;
                continue;
            }
//            如果temp和slow相遇,返回temp节点
            if (temp!=null){
                temp=temp.next;
                if (temp.equals(slow)){
                    return (Integer) temp.data;
                }
            }
        }
//        如果跳出循环,说明不是环形队列,自然就没有入口
        return null;
    }

    public static void main(String[] args) {
//        创建节点,采用这样的方式创建,节点数改为偶数个
        Node<Integer> a=new Node<Integer>(1,null);
        Node<Integer> b=new Node<Integer>(2,null);
        Node<Integer> c=new Node<Integer>(3,null);
        Node<Integer> d=new Node<Integer>(4,null);
        Node<Integer> e=new Node<Integer>(5,null);
        Node<Integer> f=new Node<Integer>(6,null);
        Node<Integer> g=new Node<Integer>(7,null);

//        节点指向性
        a.next=b;
        b.next=c;
        c.next=d;
        d.next=e;
        e.next=f;
        f.next=g;
//        添加环形,环形入口节点为c
        g.next=c;
//        调用方法
        System.out.println("是否是环形链表:"+isCircle(a));
        System.out.println("环的入口元素值:"+entrance(a));
    }
}

在这里插入图片描述
关于找入口的数学原理,参考以下文章,我没看太懂:
[寻找环链表入口点] 快慢指针数学原理剖析

发布了235 篇原创文章 · 获赞 24 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_44663675/article/details/105470455