链表经典面试题三

题型十一:判断单链表是否带环,若带环,求出环的长度,环的入口点,

1、判断是否带环:

判断一个链表是否带环的带环的条件是,当链表不带环时尾节点指向空,当链表带环时,链表没有尾节点。

ListNode* IsCycle(ListNode* pHead)//判断链表是否带环,若带环,返回快慢指针相遇的节点
{
     ListNode* cur = pHead;
     ListNode* slow = pHead;
     ListNode* fast = pHead;
     while (cur)
     {
          cur = cur->pNext;
          while (fast&&fast->pNext)
          {
              slow = slow->pNext;
              fast = fast->pNext->pNext;
              if (slow->data == fast->data)
              {
                   return slow;
              }
          }
     }
     return NULL;//不带环,最后一个节点指向NULL
}

2、求环的长度:

分析:用快慢指针遍历这个带环的链表,当快慢指针指向的节点相等时,那么此时,这个节点一定在环内,在从这个节点出发,节点将会一直在这个环里面遍历,当再次回到快慢指针相遇的节点处,刚好遍历完整个环,再次过程中,用一个计数器计数,就可以记录下整个环的长度。

int GetLenth(ListNode* pHead)
{
     ListNode* meet;
     ListNode* cur;
     meet = IsCycle(pHead);
     int count=0;
     cur = meet->pNext;
     while (cur->data != meet->data)
     {
          cur = cur->pNext;
          count++;
     }
     return count;
}

3、求环的入口点:

分析:

题型十二:判断两个链表是否相交,若相交,求交点(假设链表不带环)

分析:第一步,判断两个链表是否相交,相交的两个链表一定满足两个链表的倒数第一个节点是相同的,根据这个条件就可以很轻松的写出代码了。
第二步:求两个链表的交点,那么也就是说找到找到两个相交链表中第一个相同的节点。分别求两个链表的长度,求出长度之差k,让长链表先走k步,两个链表再一起往后走,直到两个节点相遇,返回这个相遇的值,就是两个链表的交点。代码如下:

判断是否相交:

int IsIntersect(ListNode* List1, ListNode* List2)
{
     ListNode* tail1 = List1;
     ListNode* tail2 = List2;
     while (tail1->pNext)
     {
          tail1 = tail1->pNext;
     }
     while (tail2->pNext)
     {
          tail2 = tail2->pNext;
     }
     if (tail1->data == tail2->data)
     {
          return 1;
     }
     else
          return 0;
}

找出两个相交链表的交点:

ListNode* MeetNode(ListNode* List1, ListNode* List2)
{
     int l1 = ListLength(List1);
     int l2 = ListLength(List2);
     int k = abs(l1 - l2);
     int ret = IsIntersect(List1, List2);
     ListNode* cur1 = List1;
     ListNode* cur2 = List2;
     if (ret = 0)
          return NULL;
     else
     {
          if (l1 >= l2)
          {
              while (k)
              {
                   cur1 = cur1->pNext;
                   k--;
              }
              while (cur1->data != cur2->data)
              {
                   cur1 = cur1->pNext;
                   cur2 = cur2->pNext;
              }
              return cur1;
          }
          cur1 = List1;
          cur2 = List2;
          if (l1 < l2)
          {
              while (k)
              {
                   cur2 = cur2->pNext;
                   k--;
              }
              while (cur1->data != cur2->data)
              {
                   cur1 = cur1->pNext;
                   cur2 = cur2->pNext;
              }
              return List1;
          }
     }

}

题型十二:判断两个链表是否相交,若相交,求交点(假设链表可能带环)
这个题型就有些复杂了,它包含了很多情况,




情况一和情况二都是无环链表的知识,在题型十一就有详细的解释。情况三、一个链表带环,一个链表不带环,这样的两个链表一定是不相交的。当两个链表都带环时,分为 三种情况两个链表不想交,交点在环外,交点在环内。分别求出两个链表的环的入口点,如果两个链表的入口点是相同的那么就是环外相交,如果两个链表环的入口点不相同,那么就是情况六,环内相交。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值