Java判断单链表环单问题

12 篇文章 0 订阅
11 篇文章 0 订阅

1、如何判断一个单链表是否存在闭环;

2、求闭环长度

3、求入环节点

代码实现:

package com.sort.demo;

import com.sort.demo.pojo.Node;

/**
 * 关于单链表闭环问题
 */
public class NodeCycle {

    /**
     * 判断是否存在闭环
     * <p>
     * 思路:两个指针分别指向起始位置,P1每次移动一步,P2每次移动2步;当P1 == P2时则表示存在闭环
     *
     * @param root
     * @return
     */
    public static boolean isCycle(Node root) {
        if (getFirstMeetNode(root) != null) {
            return true;
        }
        return false;
    }

    private static Node getFirstMeetNode(Node root) {
        Node p1 = root;
        Node p2 = root;
        while (p2 != null && p2.next != null) {
            p1 = p1.next;
            p2 = p2.next.next;

            if (p1 == p2) {
                return p1;
            }
        }
        return null;
    }

    /**
     * 获取闭环长度
     * 首次相遇点到再次相遇,P2刚好比P1多一圈
     *
     * @param root
     * @return
     */
    public static int cycleLength(Node root) {
        Node p1 = getFirstMeetNode(root);
        Node p2 = p1;
        int step1 = 0;
        int step2 = 0;
        while (p2 != null && p2.next != null) {
            p1 = p1.next;
            step1++;
            p2 = p2.next.next;
            step2 += 2;
            if (p1 == p2) {
                return step2 - step1;
            }
        }
        return -1;
    }

    /**
     * 获取入环节点
     * @param root
     */
    public static Node enterCycleNode(Node root) {
        Node p1 = getFirstMeetNode(root);
        Node p2 = root;
        while (p1 != null && p2 != null) {
            p1 = p1.next;
            p2 = p2.next;
            while (p1 == p2) {
                return p1;
            }
        }
        return null;
    }

    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);
        Node node6 = new Node(8);
        Node node7 = new Node(1);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        node6.next = node7;
        node7.next = node4;

        System.out.println("是否存在闭环:" + isCycle(node1));
        System.out.println("闭环长度:" + cycleLength(node1));
        System.out.println("入环节点:" + enterCycleNode(node1).data);
    }
}

运行结果:

是否存在闭环:true
闭环长度:4
入环节点:2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值