每日打卡:环形链表

186 阅读2分钟

这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

原题链接

快过年了,做一点简单题开心一下。

这一道题我们就很容易想到我们前几天刚做的相交链表的解法,我们使用哈希表存储我们的链表,发现是否有重复的部分就很容易地解决了。

public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> seen = new HashSet<ListNode>();
        while (head != null) {
            if (!seen.add(head)) {
                return true;
            }
            head = head.next;
        }
        return false;
    }
}

既然都已经在做简单题了,还要用哈希表去算,这个样子下去,我们是不会进步的,在这一道题中,我们还可以使用快慢指针的的方式

首先,我们先定义两个指针,一个是快指针,一个是慢指针,一前一后,一快一慢,如果我们这个链表存在环,那么我们的指针就会因为快慢的原因总有一天就会相遇,就像我们人一样,两个人有缘分(环),不管怎么样,兜兜转转,总会相遇。

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode left = head, right = head;
        //因为快指针的缘故,我们就只需要判断我们的快指针的是否为空就可以了
        while(right != null && right.next != null){ 
            left = left.next;
            right = right.next.next;
            if(left == right) return true;
        }
        return false;
    }
}

最后,是不是以为这就结束了,不不不,你错了,我们开始整活了,

仔细读题,我们发现我们的节点长度不超过10000,这意味着什么?!我们的只要一直循环,超过一万次他就是有环,为什么?因为如果有环,我们就会陷入循环,遍历肯定会超过10000次,如果没有环,遍历到最后就结束了,他也不会超过10000次

public class Solution {
    public boolean hasCycle(ListNode head) {
            int n = 0;
        while(head!=null){
            head = head.next;
            n++;
            if(n > 10000)return true;
        }
        return false;
    }
}

但是,建议大家没要这么皮,因为我们只是单纯的循环和判断,次数也不是很多,我们还可以通过这种方式来解决,如果我们之后的题计算量比较大的,一定会超时。