327-Leetcode 环形链表

在这里插入图片描述
方法一:哈希表

用哈希表来存储所有已经访问过的节点。每次我们到达一个节点,如果该节点已经存在于哈希表中,则说明该链表是环形链表,否则就将该节点加入哈希表中。重复这一过程,直到我们遍历完整个链表即可

struct ListNode
{
	int val;
	ListNode* next;
	ListNode(int x) : val(x), next(NULL) {}
};
class Solution
{
public:
	bool hasCycle(ListNode* head)
	{
		if (head == nullptr) return false;
		unordered_map<ListNode*,int> map;
		while (head != nullptr)
		{
			if (map.count(head))
			{
				return true;
			}
			map.insert({ head,1 });
			head = head->next;
		}
		return false;
	}
};
int main()
{
	Solution A;
	ListNode* head = new ListNode(0);
	ListNode* p = head;
	for (int i = 1; i < 4; ++i)
	{
		p->next = new ListNode(i);
		p = p->next;
	}
	p->next = head;
	cout << A.hasCycle(head) << endl;
	return 0;
}

时间复杂度:O(N),其中 N 是链表中的节点数。最坏情况下我们需要遍历每个节点一次

空间复杂度:O(N),其中 N 是链表中的节点数。主要为哈希表的开销,最坏情况下我们需要将每个节点插入到哈希表中一次

方法二:快慢指针

struct ListNode
{
	int val;
	ListNode* next;
	ListNode(int x) : val(x), next(NULL) {}
};
class Solution
{
public:

	bool hasCycle(ListNode* head)
	{
		if (head == nullptr || head->next == nullptr)
		{
			return false;
		}
		ListNode* slow = head;
		ListNode* fast = head->next;
		while (slow != fast)
		{
			if (fast == nullptr || fast->next == nullptr)
			{
				return false;
			}
			slow = slow->next;
			fast = fast->next->next;
		}
		return true;
	}
};
int main()
{
	Solution A;
	ListNode* head = new ListNode(0);
	ListNode* p = head;
	for (int i = 1; i < 4; ++i)
	{
		p->next = new ListNode(i);
		p = p->next;
	}
	p->next = head;
	cout << A.hasCycle(head) << endl;
	return 0;
}

时间复杂度:O(N),其中 N 是链表中的节点数
当链表中不存在环时,快指针将先于慢指针到达链表尾部,链表中每个节点至多被访问两次
当链表中存在环时,每一轮移动后,快慢指针的距离将减小一。而初始距离为环的长度,因此至多移动 N 轮

空间复杂度:O(1)我们只使用了两个指针的额外空间

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值