判断两个可能有环的链表相交问题

①链表是否有环,若有环,返回第一个入环节点?

方法:设置两个指针,快指针一次走两步,慢指针一次走一步,若快指针走到空节点,则说明无环,否则,等到两个指针在环内相遇,将快指针指向头节点,两个节点同时开始一次走一步,一定会在入环处相遇。

Node* getLoopNode(Node* root) {
	if (root == nullptr || root->next == nullptr || root->next->next == nullptr)
		return nullptr;
	Node* slow = root->next;
	Node* fast = root->next->next;
	while (fast != slow) {
		slow = slow->next;
		if (fast == nullptr || fast->next == nullptr)	return nullptr;
		fast = fast->next->next;
	}
	fast = root;
	while (fast != slow) {
		fast = fast->next;
		slow = slow->next;
	}
	return fast;
}


②链表是否相交,若相交,返回第一个相交节点?

方法:分情况讨论,若两个链表都无环,则可以先求出两个链表的长度n,m(n>m),并判断他们的最后一个节点是否相同,若不相同,则一定不相交,若相同,则先让长链表走n-m步,之后,另一个链表也开始走,判断他们的每一次节点是否相同,若相同,则说明返回即可;若两个链表有环,则先看两个链表的入环节点是否相同,若相同,则说明相交节点在入环节点前,

//先考虑无环情况和相交节点在公共入环节点前
Node* getNode(Node* root1, Node* root2, Node* N) {//N表示他们共同的入环节点
	int size = 0;//记录链表1长度-链表2长度
	Node* node1 = root1;
	while (node1->next != N) {
		size++;
		node1 = node1->next;
	}
	Node* node2 = root2;
	while (node2->next != N) {
		size--;
		node2=node2->next;
	}
	if (node1 != node2)	return nullptr;
	node1 = size > 0 ? root1 : root2;
	node2 = node1 == root1 ? root2 : root1;
	size = abs(size);
	while (size-- != 0)	node1 = node1->next;
	while (node1 != node2) {
		node1 = node1->next;
		node2 = node2->next;
	}
	return node1;

}
Node* getFirstNode(Node* root1, Node* root2) {
	Node* t1 = getLoopNode(root1);
	Node* t2 = getLoopNode(root2);
	if (t1 == nullptr && t2 == nullptr) {//说明无环
		return getNode(root1, root2, nullptr);
	}
	else if (t1 != nullptr && t2 != nullptr) {//说明都有环
		if (t1 == t2) {//说明在入环前相遇了。
			return getNode(root1, root2, t1->next);
		}
		else {//则要么不相交,要么环内相交
			Node* cur = t1->next;
			while (cur != t1) {
				if (cur == t2)	return t2;
				cur = cur->next;
			}
			return nullptr;
		}
	}
	else {//说明一个有环,一个没有,则不可能相交
		return nullptr;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值