环形链表的问题

链表是否有环

         7<-6

(向下)v ^(向上)
1->2->3->4->5

如何判断链表是否有环,可以通过快慢指针的方式,比如 快一次走俩格,慢指针一次走一格,当存在环时,快慢指针最终会在环里相遇。

package algorithm;

public class Circle {


    public static boolean isCycle(Node head) {

        Node fastP = head;
        Node slowP = head;
        while(fastP!=null && fastP.next!=null){
            if(fastP.val == slowP.val){
                return true;
            }
            slowP=slowP.next;
            fastP=fastP.next.next;
        }

        return false;
    }


    private static class Node{
        private Integer val;
        private Node next;

        public Node(Integer val) {
            this.val = val;
        }
    }

    public static void main(String[] args) {
        Node node1= new Node(5);
        Node node2 = new Node(3);
        Node node3 = new Node(7);
        Node node4 = new Node(2);
        Node node5 = new Node(6);
        node1.next=node2;
        node2.next=node3;
        node3.next=node4;
        node4.next=node5;
        node5.next=node2;
        System.out.println(isCycle(node1));
    }
}

结果
true

Process finished with exit code 0

链表的环长是多少

如何计算环的长度,从快慢指针相遇开始,到下次相遇,他俩的速度差*前进的次数就是环长

package algorithm;

public class CycleLength {

    public static Integer cycleLength(Node head) {

        Node fastP = head;
        Node slowP = head;
        int len = 0;
        int meetNumber = Integer.MAX_VALUE;
        while (fastP != null && fastP.next != null) {
            if (fastP.val == slowP.val && meetNumber!=Integer.MAX_VALUE) {
               return len;
            }

            if (fastP.val == slowP.val ) {
                meetNumber = fastP.val;
            }
            if(meetNumber!=Integer.MAX_VALUE){
                len++;
            }
            slowP = slowP.next;
            fastP = fastP.next.next;
        }
        return 0;
    }




    private static class Node {
        private Integer val;
        private Node next;

        public Node(Integer val) {
            this.val = val;
        }
    }

    public static void main(String[] args) {
        Node node1 = new Node(5);
        Node node2 = new Node(3);
        Node node3 = new Node(7);
        Node node4 = new Node(2);
        Node node5 = new Node(6);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node2;
        System.out.println(cycleLength(node1));
    }
}

结果
4

Process finished with exit code 0

链表环的入口结点

如果一个链表分为 入环长度 D,环内相遇点,慢指针走的长s1,快指针走的长s2,本题快指针速度是慢指针2倍,所以有公式
2(d+s1) = d+s1+n(s1+s2)
d=(n-1)(s1+s2)


无代码

以上时环形链表可能会遇到的三个典型问题,主要考察的是链表遍历以及对环的理解,至于其他链表操作,比如倒序遍历,双链比较排序等

posted @ 2021-11-19 17:37  小傻孩丶儿  阅读(9)  评论(0编辑  收藏  举报