剑指offer--判断链表是否带环?若带环求环的长度?若带环求环的入口点?

1、判断链表是否带环?

链表是否带环,可以采用快慢指针法,用两个指针指向链表的头结点,一个指针一次向后走一个位置,另一个指针向后走两个位置,这样如果两个指针如果相遇,这样就能说该链表带环,如果当快指针或者快指针的next为NULL时,还没有相遇。哪么就说明该链表不带环。

我实现时,用一个pair模板去实现,这样为了方便后面两个问题的解决。

代码实现:

#include<assert.h>
struct ListNode{
	int val;
	ListNode* next;
	ListNode(int _val)
		:val(_val)
		, next(NULL)
	{}
};

pair<ListNode*, bool> IsExitsLoop(ListNode* Head)  //求环
{
	assert(Head != NULL);
	ListNode* slow = Head;  //快指针
	ListNode* fast = Head;  //慢指针

	while (slow != NULL && slow->next != NULL)
	{
		slow = slow->next->next;
		fast = fast->next;
		if (slow == fast)
			return make_pair(fast, true);
	}

	return make_pair(slow, false);
}

2、若带环则求环的长度?

当链表带环时,我们可以发现从两个快慢指针相遇的结点走一圈,就能求出该环的长度。

代码实现:

int length(pair<ListNode*, bool> l)
{
	if (l.second == false)
		exit(1);
	int length = 0;
	ListNode* node = l.first;
	do{
		length++;
		node = node->next;
	} while (node != l.first);
	return length;
}

3、若带环则求环的入口点?

当带环时,要求带环的入口点。这个我们可以利用数学知识去计算。

假设链表总长为L,头节点到入口点的距离为a,入口点到快慢指针交点距离为x,环的长度为R,现在假设慢指针走了S步与快指针相遇,那么慢指针走的路程为S=a+x;快指针走的路程为2S = a+x+nR;那么a+x=nR;

a = nR-x;

那么我们可以知道快慢指针相交节点之后,再另一个指针去指向头结点,我们让这个指针与在相交节点的指针去共同向后走,直到两个节点相交,这个时候这个的节点就是我们所要求的的入口节点。

代码实现:

ListNode* FindLoopPort(ListNode* head)
{
	ListNode* ptr = head;
	ListNode* end = NULL;
	if (IsExitsLoop(head).second)
	end = IsExitsLoop(head).first;

	while (ptr != end)
	{
		ptr = ptr->next;
		end = end->next;
	}
	if (ptr == end)
		return ptr;
	else
		return NULL;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值