链表中环的入口节点(剑指offer-23)

1、题目描述

    给定一个带环的链表,找出链表中环的入口节点。

2、解题思路

(1)求出环中节点的总数

    使用两个指针,一个快指针fast和一个慢指针slow,向前移动时,快指针每次移动两个节点,慢指针每次移动一个节点,当快指针和慢指针相等时,它们两此一次在环中相遇。接着,按照以上策略继续向前移动,同时用两个计数器分别统计快指针fast和慢指针slow的前进步数,当两个指针再次相遇时,快指针的步数减去慢指针的步数即为环中节点的总数count。

(2)求出环的入口节点

    当已知环中节点的总数count时,接着使用两个指针进行移动。第一个指针先向前移动环的节点总数count步,此时两个指针刚好相差一个环的距离count。接着两个指针同时向前移动,当两个指针相等时,说明达到了环的入口节点。代码如下:

#include<iostream>
#include<vector>
using namespace std;

//定义链表节点
typedef struct LNode
{
	int value;
	struct LNode *next;
}LNode;

//指定链表节点总数和环入口,创建一个带环的链表
LNode* CreateList(int num,int circle) {	
	LNode *head = (LNode *)malloc(sizeof(LNode));
	head->value = 0;
	head->next = NULL;
	LNode *entry_node = NULL;
	LNode *end_node = head;
	for (int i = 1; i < num; i++) {
		LNode *node = (LNode *)malloc(sizeof(LNode));
		node->value = i*i;
		node->next = NULL;
		end_node->next = node;
		end_node = node;
		if (i == circle)
			entry_node = end_node;			
	}
	end_node->next = entry_node;
	return head;
}

//返回链表中环总共的节点数
int NodeNumOfCircle(LNode *head) {
	LNode *slow = head;
	LNode *fast = head;
	int meet = 0;
	int sum_slow = 0;
	int sum_fast = 0;
	while (1) {
		fast = fast->next;
		if (fast == slow)break;
		fast = fast->next;
		if (fast == slow)break;
		slow = slow->next;
		if (slow == fast)break;	
	}
	while (1) {
		fast = fast->next;
		sum_fast++;
		if (fast == slow)break;
		fast = fast->next;
		sum_fast++;
		if (fast == slow)break;
		slow = slow->next;
		sum_slow++;
		if (slow == fast)break;
	}
	return sum_fast - sum_slow;
}

//判断带环的链表中环的入口节点
void CircleInLinkedList() {
	LNode *head = CreateList(10,8);
	int num = NodeNumOfCircle(head);
	LNode *p = head;
	LNode *q = head;
	while (num > 0) {
		p = p->next;
		num--;
	}
	while (p != q) {
		p = p->next;
		q = q->next;
	}
	cout << p->value<<endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值