链表面试题 进阶

1.判断单链表是否带环?若带环,求环的长度?求环的入口点?

2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)

3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】 



1.判断单链表是否带环?若带环,求环的长度?求环的入口点?

判断链表是否带环:


//检查链表是否带环
//快慢指针
void Check_Ring(ListNode* pList)
{
	//1链表为空
	//2链表不为空
	ListNode* slow = pList;
	ListNode* fast = pList;
	if(pList == NULL)
	{
	   printf("此链表不带环\n");
	   return ;
	}
	else
	{
		while(fast != NULL && fast->next != NULL)
		{
			slow = slow->next;
			fast = fast->next->next;
			if(slow->next == fast->next)
			{
				printf("此链表带环\n");
				return ;
			}
		}
		printf("链表不带环\n");
	}
}
求环长度:


//求一个带环链表环的长度
void Length_Of_Ring(ListNode* pList)
{
	ListNode* fast = pList->next->next;
	ListNode* slow = pList;
	ListNode* pos;
	int count=0;
	assert(pList);
	
	while(slow != fast)
	{
		slow = slow->next;
		fast = fast->next->next;
	}
	if(fast == slow)
		{
		  pos = slow;
		  slow = slow->next;
		  while(slow!=pos)
		  {
		    count++;
			slow = slow->next;
		  }
		  count++;
		  printf("环的长度为:%d  \n",count);
		} 
}
求带环链表的环入口点


//求一个环形链表的入环点
ListNode* Pos_to_Enter_ring(ListNode* pList)
{
	
	ListNode* fast = pList->next->next;
	ListNode* slow = pList;
	ListNode* curPlist = pList;
	ListNode* newhead;
	ListNode* curnewhead;
	assert(pList);

	//找到交点
	while(slow != fast)
	{
		slow =slow->next;
		fast = fast->next->next;
	}
	//断开交点
	newhead = slow->next;
	curnewhead = newhead; 
	slow->next = NULL;
	//找两条链的交点
	while(curPlist!= NULL)
	{
		while(curPlist != curnewhead && curnewhead != NULL)
		{
		   curnewhead=curnewhead->next;
		}
		if(curnewhead == curPlist)
		{
		   return curnewhead;
		}
	curPlist=curPlist->next;
	curnewhead=newhead;
	}
}

2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)


//判断两条不带环链表是否相交
void juge_no_ring_list_intersect(ListNode* pList1,ListNode* pList2)
{
	//
	ListNode* curpList1 = pList1;
	ListNode* curpList2 = pList2;
	assert(pList1&&pList2);
	//判断尾节点是否相同即可
	while(curpList1->next)
	{
		curpList1 = curpList1->next;
	}
	while(curpList2->next)
	{
		curpList2=curpList2->next;
	}
	if(curpList1 == curpList2)
	{
	   printf("这两条链表相交\n");
	}
	else
	{
	   printf("这两条链表不相交\n");
	}
}

//求交点的思想和求环入口点的方法一样,在第二条链表里面找第一条链表的第一个公共点就行


3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】 



1首先利用快慢指针和一些其他方法判断情况两条链表的基本情况。

2在情况分类清楚以后再对各种情况进行针对性的相交甄别

//考虑两条链表带环或者不带环
void juge_list_intersect(ListNode* pList1,ListNode* pList2)
{
//一:两条链表不带环
//       1相交 2不想交
//二:一条链表带环,另一条链表不带环
//       1不相交
//三:两条链表都带环
//       1相交  2不相交

	ListNode* curpList1 = pList1;
	ListNode* curpList2 = pList2;
	ListNode* slow1 = pList1 ;
	ListNode* fast1 = pList1;
	ListNode* slow2 = pList2;
	ListNode* fast2 = pList2;
	int flag1 = 0;  //等于1 链表带环 等于0  链表不带环
	int flag2 = 0;
	assert(pList1&&pList2);
	//进行情况判断
    while(fast1 && fast1->next)
	{
	   slow1 = slow1->next;
	   fast1 = fast1->next->next;
	   if(slow1 == fast1)
		 {
			 flag1 = 1;
			 break;
	     }
	}
	while(fast2 && fast2->next)
	{
	    slow2 =slow2->next;
		fast2 =fast2->next->next;
		if(slow2 == fast2)
		{
			flag2 = 1;
			break;
		}
	}
	//都不带环
	if(flag1 == 0 && flag2 == 0)
	{
		printf("这是两条不带还的链表\n");
		juge_no_ring_list_intersect(curpList1,curpList2);
	}
	//其中一个为带环 另外一个不带环
	else if((flag1 == 1 && flag2 == 0) ||(flag2 == 1 && flag1 == 0))
	{
	      printf("这两条链表的其中一条链表带环   这两条链表不相交\n");
	}
	else//两个都带环
		{
             //找到其中一个环的入口点
			 ListNode* enterpos = Pos_to_Enter_ring(pList1);
			 fast2 = pList2;
			 slow2 = pList2;

			 while(fast2 && fast2->next)
			 {
				 slow2 = slow2->next;
				 fast2 = fast2->next->next;
				 if(enterpos == slow2)
				 {
				    printf("这两条带环链表 相交\n");
					break;
				 }
			      if(slow2 == fast2)
				  {
					  printf("这两条带环链表不相交\n");
				     break;
				  }
			 }
	    }
}
//判断交点的思想上面也已经提过就不再写了

关于链表的问题思想最重要,当了解了思想以后,写代码就容易很多。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值