题解 | #判断链表中是否有环#

判断链表中是否有环

http://www.nowcoder.com/practice/650474f313294468a4ded3ce0f7898b9

算法思想一:双指针

解题思路:

我们使用两个指针,fast 与 slow。
它们起始都位于链表的头部。随后,slow 指针每次向后移动一个位置,而fast 指针向后移动两个位置。如果链表中存在环,则 fast 指针最终将再次与 slow 指针在环中相遇。
图解:

代码展示:

Python版本
class Solution:
    def hasCycle(self , head ):
        # write code here
        if not head:
            return head
        # 双指针  快慢指针
        slow = head
        fast = head
        while slow and fast:
            slow = slow.next
            if fast.next:
                fast = fast.next.next
            else:
                return False
            # 当双指针相遇 即表示指针有环
            if slow == fast:
                return True
        return False

复杂度分析:

时间复杂度O(N):其中 N 为链表中节点的数目。在最初判断快慢指针是否相遇时,slow 指针走过的距离不会超过链表的总长度
空间复杂度O(1):额外使用的指针占用常数空间

算法思想二:哈希表

解题思路:

我们遍历链表中的每个节点,并将它记录下来;一旦遇到了此前遍历过的节点,就可以判定链表中存在环。借助哈希表可以很方便地实现
1、遍历链表,并将访问过的结点存储到哈希表中
2、判断结点是否在哈希表中,若存在则返回 true
3、遍历结束,则返回 false

代码展示:

JAVA版本
public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode pos = head;
        // 哈希表记录访问过的结点
        Set<ListNode> visited = new HashSet<ListNode>();
        while (pos != null) {
            // 判断结点是否被访问
            if (visited.contains(pos)) {
                return true;
            } else {
                // 结点记录添加到哈希表中
                visited.add(pos);
            }
            // 遍历
            pos = pos.next;
        }
        return false;
    }
}

复杂度分析:

时间复杂度O(N):其中 N 为链表中节点的数目。遍历整个链表的结点
空间复杂度O(N):其中 N 为链表中节点的数目。我们需要将链表中的每个节点都保存在哈希表当中。





全部评论
双指针还能这么用,厉害
2 回复 分享
发布于 2022-05-14 22:36
if not head: return False
5 回复 分享
发布于 2021-12-28 21:14
快慢指针原理说明:1.单向链表中如果有环,一定是最后一个结点的后继指针又指向了已遍历结点(这个已遍历结点可以称为三叉结点,因为该结点有两个入口一个出口),从而形成环。2.因为有环的存在,所以以后继结点非空为条件进行的遍历永远不会停止。3.当慢指针首次到达三叉结点,也就是慢指针开始进入环中时,快指针可能位于环中任一结点处:快指针可能落后慢指针0个结点(快慢指针均位于三叉结点,即刚好相遇)、落后1个结点、2个结点、3个等等,最多落后L-1个节点(L是环中结点总数,即快指针恰位于慢指针的后继结点处)。由于快指针每一跳都比慢指针多前进一个位置,因此,快指针最多也只需要L-1跳就追上慢指针(相遇)。如果是L-1跳后两指针才首次相遇,此时,慢指针刚好来到链表最后一个结点(三叉结点的前驱结点)。因此可以断言:快慢指针首次相遇时,慢指针走过的距离不超过链表的总长度。ps:纯文字描述可能难以理解,可以画图辅助,将三叉结点标记为L号结点,画一个包含L个结点的环即可。
3 回复 分享
发布于 2022-11-08 12:34 浙江
hash表解题不对吧,链表中存在重复元素也算存在环???
2 回复 分享
发布于 2022-02-14 14:05
不要用contains 直接判断add 能不能添加成功,
2 回复 分享
发布于 2022-03-24 20:45
断言:如果有环,快慢指针一定会在环中相遇,且首次相遇时,慢指针走过的距离不超过链表的总长度。
2 回复 分享
发布于 2022-11-08 12:54 浙江
双指针方法不需要去判定空链表,否则会多余输出null
1 回复 分享
发布于 04-14 21:22 海南
最后那一行 return false 是不是多余呀? 上面两个return 已经包含了所有情况
点赞 回复 分享
发布于 2021-09-14 00:23
按你这个图,快慢指针在节点6相遇
点赞 回复 分享
发布于 2023-03-06 15:10 广东

相关推荐

11-18 09:44
Java
小白也想要offer:简历别放洋屁,搞不还还放错了,当然你投外企除外,以上纯属个人观点
点赞 评论 收藏
分享
评论
63
17
分享
牛客网
牛客企业服务