小鑫的算法之路:leetcode0141 环形链表

题目

给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。

注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

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

进阶:你能用 O(1)(即,常量)内存解决此问题吗?

解法1:哈希去重

判断链表中是否成环,可以通过一个哈希表保存已遍历的所有指针节点。如果下一个指针节点为空,那么肯定不成环。如果下一个指针节点不为空,且节点已经在保存的哈希表中,那么可以判断成环。

代码如下:

class Solution {
public:
    bool hasCycle(ListNode *head) {
        unordered_set<ListNode*> buffer{};
        while (head != nullptr) {
            if (buffer.find(head) != buffer.end()) {
                return true;
            }
            buffer.insert(head);
            head = head->next;
        }
        return false;
    }
};

时间复杂度和空间复杂度均为O(n),执行结果如下:

在这里插入图片描述

解法2:快慢指针

解法1中空间复杂度为O(n),在题目中进阶要求为O(1)。快慢指针是链表中的一种典型应用方案,本题也可以应用该方案。初始化两个指针,一个快指针,每次走两步,一个慢指针,每次走一步。如果成环,那么快指针肯定会追到慢指针。否则,如果不成环,快指针最终会遍历到链表的尾部。

代码如下:

class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* slow_node = head;
        ListNode* fast_node = head;
        while ((fast_node != nullptr) && (fast_node->next != nullptr)) {
            fast_node = fast_node->next->next;
            slow_node = slow_node->next;
            if (fast_node == slow_node) {
                return true;
            }
        }
        return false;
    }
};

时间复杂度为O(n),空间复杂度为O(1)。执行结果如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值