判断链表是否成环及环周长与未成环长度计算

1.判断是否成环
使用快慢指针法,2个指针分别以每次1个节点和每次两个节点的速度前进,若快指针指向nullptr,则无环路存在。当两指针相遇,则证明有环存在。
C++代码:

bool hasCircle(ListNode* node)
	{
		ListNode* fast = node, *slow = node;
		while (fast != nullptr && fast->next != nullptr)
		{
			fast = fast->next->next;
			slow = slow->next;
			if (fast == slow)
				return true;
		}
		return false;
	}

2.环的周长计算
先判断是否成环,两指针相遇后继续向前,第二次相遇时两者路程差即为环周长。
C++代码:

int Circumference(ListNode* node)
	{
		ListNode* fast = node, *slow = node;
		bool hasCircle = false;
		while (fast != nullptr && fast->next != nullptr)
		{
			fast = fast->next->next;
			slow = slow->next;
			if (fast == slow)
			{
				hasCircle = true;
				break;
			}
		}
		if (!hasCircle)
			return 0;
		int cir = 0;
		do
		{
			cir++;
			fast = fast->next->next;
			slow = slow->next;
		} while (fast != slow);
		return cir;
	}

3.未成环的长度计算
依然先判断是否成环,若未成环则return链表总长度。
下面进行成环情况下的分析

在这里插入图片描述
设第一次相遇时,slow指针走过的距离为S,在环上走过的距离为D,则快指针走过的速度为2S;设环周长为C。
2 S = D + L + n C , S = D + L , S = n C 易知: 2S = D+L+nC,S = D+L,S = nC
L = S D = ( n 1 ) C + C = ( n 1 ) C + C D L = S-D=(n-1)C+C=(n-1)C+C-D
即在慢指针走过(n-1)圈加(C-D)的距离时,在链表头的慢指针走过L的长度。
所以从相遇点出发的慢指针和在表头出发的慢指针会在环的交界点相遇。此时指针走过的距离为L.
C++代码:

	int unCircleLen(ListNode* node)
	{
		ListNode* fast = node, *slow = node;
		bool hasCircle = false;
		int unCirLen = 0;
		while (fast != nullptr && fast->next != nullptr)
		{
			fast = fast->next->next;
			slow = slow->next;
			if (fast == slow)
			{
				hasCircle = true;
				break;
			}
			unCirLen++;
		}
		if (!hasCircle)
		{
			fast == nullptr ? unCirLen = 2 * unCirLen : 2 * unCirLen + 1;
			return unCirLen;
		}
		unCirLen = 0;
		ListNode* slow2 = node;
		while (slow != slow2)
		{
			unCirLen++;
			slow = slow->next;
			slow2 = slow2->next;
		}
		return unCirLen;
	}

全部代码:

struct ListNode {
     int val;
     ListNode *next;
     ListNode(int x) : val(x), next(NULL) {}
};
class Solution
{
public:
	bool hasCircle(ListNode* node)
	{
		ListNode* fast = node, *slow = node;
		while (fast != nullptr && fast->next != nullptr)
		{
			fast = fast->next->next;
			slow = slow->next;
			if (fast == slow)
				return true;
		}
		return false;
	}
	int Circumference(ListNode* node)
	{
		ListNode* fast = node, *slow = node;
		bool hasCircle = false;
		while (fast != nullptr && fast->next != nullptr)
		{
			fast = fast->next->next;
			slow = slow->next;
			if (fast == slow)
			{
				hasCircle = true;
				break;
			}
		}
		if (!hasCircle)
			return 0;
		int cir = 0;
		do
		{
			cir++;
			fast = fast->next->next;
			slow = slow->next;
		} while (fast != slow);
		return cir;
	}
	int unCircleLen(ListNode* node)
	{
		ListNode* fast = node, *slow = node;
		bool hasCircle = false;
		int unCirLen = 0;
		while (fast != nullptr && fast->next != nullptr)
		{
			fast = fast->next->next;
			slow = slow->next;
			if (fast == slow)
			{
				hasCircle = true;
				break;
			}
			unCirLen++;
		}
		if (!hasCircle)
		{
			fast == nullptr ? unCirLen = 2 * unCirLen : 2 * unCirLen + 1;
			return unCirLen;
		}
		unCirLen = 0;
		ListNode* slow2 = node;
		while (slow != slow2)
		{
			unCirLen++;
			slow = slow->next;
			slow2 = slow2->next;
		}
		return unCirLen;
	}
};

猜你喜欢

转载自blog.csdn.net/qq_42263831/article/details/83066039