其他分享
首页 > 其他分享> > 30+链表问题(一):如何判断链表是否成环?

30+链表问题(一):如何判断链表是否成环?

作者:互联网

引子

在上一篇文章《30+链表问题:概览》的引言中,我提到了当初在校招时遇到的一道链表面试题。就是这道题了。下面是问题描述以及解决方案。

问题描述

给定一个链表,如何判断该链表是否成环?

解题思路

首先,一听到这个问题,脑子一下子映出下面这幅链表成环的图:

如图,上面就是一个已经成环的链表。标红的是头结点。

针对这个问题,我的解决方案是:

使用两个指针 slow、fast 遍历该链表,slow每次走一步,fast走两步(实际上,只需要两个指针一快一慢即可)。如果 fast 指针 走到头,那说明链表中不存在环。否则,两个指针在无尽的旅程中一定会相遇。

为了说明白这个情况:我还专门做了动态图(实际上,为了做这个动态图,我还花30大洋买了个软件。。。。):

代码实现

这里,LinkedList是我自己定义的链表类、Node是我自己定义的结点类。源码请参考附件,或《30+链表问题:概览》

/**
 * 判断一个链表是否成环
 *
 * @param list 链表
 * @return true Or false
 */
private boolean isContainCircle(LinkedList list) {
    // 两个指针,刚开始都指向 头结点
    Node slow = list.getHead();
    Node fast = list.getHead();
    // 如果链表成环,则直到量指针相遇之前,该循环将一直进行;
    while (fast != null && fast.getNext() != null) {
        /* fast 每次走两步,slow 走一步;
         * 在 fast 为null 之前,slow一定不为 null */
        slow = slow.getNext();
        fast = fast.getNext().getNext();
        // 这里直接比较其地址即可
        if (slow == fast) {
            return true;
        }
    }
    return false;
}

我们写代码测试一下:

public static void main(String[] args) {
    Main runner = new Main();
    LinkedList list = runner.buildLinkedListWithCircle();
    boolean containCircle = runner.isContainCircle(list);
    System.out.println("该链表是否包含环:" + containCircle);
}

/**
 * 构建出示例中的包含环的链表
 *
 * @return 包含环的链表
 */
private LinkedList buildLinkedListWithCircle() {
    LinkedList list = new LinkedList();
    Node nodeOf2 = null;
    for (int i = 1; i <= 7; i++) {
        Node node = new Node(String.valueOf(i) + i);
        list.add(node);
        if (i == 2) {
            nodeOf2 = node;
        }
    }
    list.add(nodeOf2);
    return list;
}

上面构建出的链表即上面我给的图片中的链表。我们执行这段代码,得到的结果如下:

该链表是否包含环:true

如果我们备注掉 buildLinkedListWithCircle 方法中的 list.add(nodeOf2); 这一行代码,再执行,得到结果:

该链表是否包含环:false

总结

在处理链表问题的时候,双指针、多指针是常见的结题方式。这种问题见得多了,感觉都是套路。

文中代码作者只是为了做个演示,有的细节并没有做严格校验。目前没有发现有严重的错误,如果有发现问题的朋友,欢迎指出哦~希望和大家一起进步~

源码附件

源代码:https://download.csdn.net/download/zereao/11705715

GitHub:https://github.com/Zereao/LinkListInterviewQuestion/tree/master/LinkedListContainCircle

参考文章

https://javarevisited.blogspot.com/2013/05/find-if-linked-list-contains-loops-cycle-cyclic-circular-check.html

标签:slow,LinkedList,30,list,fast,链表,成环,指针
来源: https://blog.csdn.net/Zereao/article/details/100576173