巧用“快指针”、“慢指针”

  有时候处理链表相关问题的时候,定义“快指针”和“慢指针“的方法有时候会极大地提高时间效率。下面是常见的几种使用这个方法的情况。假设不考虑异常输入的情况。

判断一个链表是否有环

  定义两个指针,快指针步长为2,慢指针步长为1.同时从链表头开始出发。如果链表中有环那么他们必然相遇。

 1 bool hasCycle(ListNode *head) {
 2     if(!head)
 3         return false;
 4     ListNode* fast = head->next;
 5     ListNode* slow = head;
 6     while(fast) {
 7         if(fast == slow)
 8             return true;
 9         if(fast->next&&fast->next->next){
10             fast = fast->next->next;
11             slow = slow->next;
12         }
13         else
14             return false;
15     }
16     return false;
17 }

  

求链表中倒数第k个结点

  假设链表长度为n,那么我们轻松得出这些结论:链表中的倒数第k个结点也就是正数第n-(k-1)个结点。所以我们只需要正向的让指针走n-k次,那么指针停留的结点便是倒数第k个结点。走完这个链表需要走的步长是n-1。

  我们定义两个指针,快指针先出发,走k-1步。此时它停在正数第k个结点上。慢指针也开始从链表头出发。两个指针步长都为1,走到快指针为NULL为止。快指针停止时他走的第二段路的长度就是慢指针的长度:(n-1)-(k-1)= n-k.根据第一段的推导可知此致慢指针的指向便是倒数第k个结点。

 1 ListNode* find(ListNode* head,int k)
 2 {
 3     if(!head)
 4         return NULL;
 5     ListNode* fast = head;
 6     ListNode* slow = head;
 7     for(int i=0;i<k-1;++)
 8         fast = fast->next;
 9     while(fast)
10     {
11         fast = fast->next;
12         slow = slow->next;
13     }
14     return slow;
15 }

 

求链表的中间结点

  这个比较简单。也是定义两个指针,快指针步长为2,慢指针步长为1。同时从head出发,当快指针为NULL时,慢指针就停在中间结点了。

 1 ListNode* findMid(ListNode* head)
 2 {
 3     if(!head)
 4         return NULL;
 5     ListNode* fast = head;
 6     ListNode* slow = head;
 7     while(fast = fast->next)
 8     {
 9         fast = fast->next;
10         slow = slow->next;
11     }
12     return slow;
13 }

 求环的长度

 求相遇的地点

转载于:https://www.cnblogs.com/ittinybird/p/4539354.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值