两个单链表相交的一系列问题c++

题目在本题中, 单链表可能有环, 也可能无环。 给定两个单链表的头节点 head1和head2, 这两个链表可能相交, 也可能不相交。 请实现一个函数, 如果两个链表相交, 请返回相交的第一个节点; 如果不相交, 返回null 即可。 要求: 如果链表1的长度为N, 链表2的长度为M, 时间复杂度请达到 O(N+M), 额外空间复杂度请达到O(1)分析这道题涵盖了链表相交的一系列问题 也是左...
摘要由CSDN通过智能技术生成

题目

在本题中, 单链表可能有环, 也可能无环。 给定两个单链表的头节点 head1和head2, 这两个链表可能相交, 也可能不相交。 请实现一个函数, 如果两个链表相交, 请返回相交的第一个节点; 如果不相交, 返回null 即可。 要求: 如果链表1的长度为N, 链表2的长度为M, 时间复杂度请达到 O(N+M), 额外空间复杂度请达到O(1)

分析

这道题涵盖了链表相交的一系列问题 也是左老师直播课的内容,我们可以拆分成几个问题来分步处理,

  1. 首先判断单链表是否有环,这里我们给该函数增加一个功能,如果有环则返还该链表的入口结点,没有则返回NULL.
  2. 判断两个无环链表是否相交,如果相交则返回相交节点,否则返回NULL。
  3. 判断两个有环链表是否相交,如果相交则返回相交节点,否则返回NULL。
  4. 如果一个链表有环,一个无环则则不相交返回NULL;

问题一

采用快指针慢指针的方法,具体操作是,定义一个快指针和一个慢指针,从头结点开始,快指针一次走两步,慢指针一次走一步,(如果走到某一步快指针为NULL,说明它到头了,进而说明它没形成环,返回NULL)如果快指针和 慢指针相遇了,说明是有环的,此时让快指针从新回到头结点,并且调整步伐为每一一步,和慢指针同步,当它们再次相遇时,所处的位置就是入环结点,这就是个套路,知道这么用就好了。这部分代码如下:

Node*getNode(Node*head)
{
   
	if (head == NULL)
		return NULL;
	Node*slow = head->next;
	Node*fast = head->next->next;
	while (fast != slow) {
   
		if (fast->next == NULL || fast->next->next == NULL)
		{
   
			return NULL;

		}
		fast = fast->next->next;
		slow = slow->next;
	}
	fast = head;
	while (fast != slow)
	{
   
		fast = fast->next;
		slow = slow->next;
	}
	return fast;
}

问题二

两个无环链表相交,结构就是一个Y字形,我们将两个链表各自遍历一遍,求出长度相减,就知道两个链表的相差长度,让长链表独自走相差出来的长度的距离,然后此时两个链表在同一起跑线了,同时往下走,直到结点相等,也就是他们首次相遇的地方。

Node*noLoop(Node*head1, Node*head2)
{
   
	int n = 0;
	Node*n1 = head1;
	Node*n2 = head2;
	while (n1 != NULL)
	{
   
		n++;
		n1 = n1->next;
	}
	while (n2 != NULL)
	{
   
		n--;
		n2 = n2->next;
	}
	n1 = n > 0 ? head1 : head2;
	n2 = n1 == head1 ? head2 : head1;
	n = abs(n);
	while (n!=0)
	{
    
		n--;
		n1 = n1->next;
	}
	while (n1 != n2)
	{
   
		n1 = n1->next;
		n2 = n2->next;
	}
	return n1;

}

问题三

两个有环链表 一共三种形态:
在这里插入图片描述
可以通过入口结点是否相等当做边界条件来分析,当loop1=loop2时是图2的情况,跟两个无环链表相交的情况基本一致,有一点注意就是遍历链表求长度时只需要求到入口结点的长度,将下面的环砍掉,剩下的就和问题二一致。
当loop2不等于loop1时有可能是图一也有能是图二,这时让loop1结点往下遍历,并每次查看是否能等于loop2如果有等于说明是图3这时返回loop1或者loop2都可以,如果走了一圈还没碰到lloop2,说明是图1没有相交返回NULL;

Node*loop(Nod
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值