链表面试题 进阶

来源:互联网 发布:php源代码下载 编辑:程序博客网 时间:2024/06/05 02:38

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;  } }    }}
//判断交点的思想上面也已经提过就不再写了

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





原创粉丝点击