c 链表之 快慢指针 查找循环节点(转)
上面分析了 根据这张图

推倒出 数学公式。 刚接触 不能一下弄明白。下面结合上面文章的分析。仔细推倒一下 ,
一般设置 快指针 速度是 慢指针的2倍。及 快指针每次遍历两个指针, 慢指针每次遍历1个指针。
假设上图 快慢指针 在E点相遇,那 相遇点离循环节点D 之间距离是X. 头结点A 离循环节点D 距离为K.
那么在两指针相遇时,各自走过得距离(这里可以吧上图想成是 一个操场,起点不在操场内):
慢指针:
K + X + n*(X+Y) = m;//X+Y 绕环一圈的距离;n 慢指针 总共绕了几圈在环内.
快指针:
试想下 快指针是慢指针 速度的2倍,当它们相遇时 所用的时间是一样的。那么快指针 走过得距离是
2*m;
也等于
K+X +N*(X+Y) = 2*m;//N为快指针绕过得圈数
联立做差上面两公式。
(N-n)*(X+Y) = m; 及
(N-n)*(X+Y) = K+X+n*(X+Y);//这里X+Y 环长是个定值。 假设环长为M
有:(N-n)*M = K+X+n*M;
有:K+X = (N-2*n)*M ;
最终的推倒公式 出来啦。及头节点A 到 循环节点D 的距离 加上 相遇点E离循环节点D 是 环长的整数倍。
这个公式试用于 0 型循环链表 和 6型循环链表。
对于前者 起K 和 X 都为0;快慢指针起点都是循环节点(0型 任意一点都是循环节点)
那么有 (N-2*n)*M = 0;
及 N = 2*n; 相遇时 快慢指针所绕 环的圈数 前者是后者的2倍。 可以想象速度是2呗,所用时间相同。
这里跟环有多少节点没有关系。
上面只是找到了相遇节点。如何找到循环节点。对于6型循环链表。
还是上面推倒公式:
K+X = (N-2*n)*M;//假设N-2*n = Q; 单位为圈数。
有K+X=Q*M; //再假设快慢指针能再循环节点相遇,那么X = 0;
K = Q*M; //Q 的值和K 成正比,这个公式成立条件是 快慢指针相遇 在环上的任意一个点,
假如是E点,结合公式 从E点转Q*M个节点 正好= K 。K的终点正好是循环节点D,及 如果快指针从起点A 走过K 和 慢节点 从E 走过M*Q 相遇节点正好是D循环节点,前提是快慢指针速度相同。
假设将快指针 从头节点开始。慢指针从上次快慢指针相遇点 开始。 两者已相同速度移动。
当快指针走的D 循环节点走过距离为K,慢指针 走到D 循环节点走过的距离为Q*M;
此时 二者相遇 节点就是循环节点。
分析下代码:
Node* findBeginning(Node *pHead)
{
if (NULL == pHead)
return NULL; Node *fast = pHead;
Node *slow = pHead; /*判断是否存在环*/
while (fast->pnext != NULL) //两种情况会跳出循环
{
fast = fast->pnext->pnext;
slow = slow->pnext; if (NULL == fast)
return NULL;
if (fast == slow)
break;
} if (NULL == fast->pnext) //判断是哪种情况导致跳出循环
return NULL; /*查找环起点*/
fast = pHead;
while (fast != slow)
{
fast = fast->pnext;
slow = slow->pnext;
} return fast;
}
关于快慢指针算法:
不仅限于 循环链表问题。
比如查找一个 未知长度链表中中心节点
可以先遍历长度,在遍历到长度/2处返回节点。显然这样 算法不够优化,
使用快慢指针 遍历。快指针速度为 慢得 2倍。
快指针遍历完,返回的慢指针 正好是 长度/2 的节点。
转自:http://www.cnblogs.com/tangbinblog/p/4125842.html
c 链表之 快慢指针 查找循环节点(转)的更多相关文章
- c 链表之 快慢指针 查找循环节点
参考:http://blog.csdn.net/wenqian1991/article/details/17452715 上面分析了 根据这张图 推倒出 数学公式. 刚接触 不能一下弄明白.下面结合上 ...
- 复习下C 链表操作(双向循环链表,查找循环节点)
双向循环链表 和 单向循环链表 查找循环节点 思路都是一样. 快慢指针查找法. 理论可参考 c 链表之 快慢指针 查找循环节点 typedef struct Student_Double { ]; ...
- sort-list——链表、快慢指针找中间、归并排序
Sort a linked list in O(n log n) time using constant space complexity. 链表,快慢指针找中点,归并排序. 注意判断条件fast-& ...
- 复习下C 链表操作(单向循环链表、查找循环节点)
循环链表 稍复杂点. 肯能会有0 或 6 字型的单向循环链表. 接下来创建 单向循环链表 并 查找单向循环链表中的循环节点. 这里已6字型单向循环链表为例. //创建 循环链表 Student * ...
- linked-list-cycle-ii——链表,找出开始循环节点
Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull. Follo ...
- reorder-list——链表、快慢指针、逆转链表、链表合并
Given a singly linked list L: L0→L1→…→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must do thi ...
- leetcode题目234.回文链表(快慢指针+辅助空间-简单)
题目描述: 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O( ...
- [LeetCode题解]142. 环形链表 II | 快慢指针
解题思路 本题是在141. 环形链表基础上的拓展,如果存在环,要找出环的入口. 如何判断是否存在环,我们知道通过快慢指针,如果相遇就表示有环.那么如何找到入口呢? 如下图所示的链表: 当 fast 与 ...
- 无表头单链表的总结----从a链表中删去与b链表中有相同ID的那些节点
#include"head.h" struct Student* del_same_ID(struct Student*p1, struct Student*p2) { struc ...
随机推荐
- 第一章 pyhton基础
一 .pyhton2与python3的区别 在pyhton2中,其中编码默认使用的是ascii编码,输出格式为print"xxx",输入为raw_input(“请输入”),在整型中 ...
- cocos2d-x游戏开发(一)之环境搭建篇
前言 进入研究生生涯已经有一段时间,感觉却没做些什么,实验室虽有一个很大的国家项目,但考虑到它这么的单一,总想利用业余时间做些什么,拓宽一下自己的知识面. 偶然机会,了解到cocos这个东东,恰好,实 ...
- 和为s的两个数字 和为s的连续正数序列
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出任意一对即可. #include <iostream> using namesp ...
- cs229_part2
part2 这节课主要讲的是生成式模型,那么与这个生成式模型相对于的就是我们上节课所讲那几个辨别式模型.所以生成式模型和辨别式模型的区别是什么呢.我先给出数学上的定义: 这是我们上节课线性回归所用的给 ...
- python中set()函数的用法
set顾名思义是集合,里面不能包含重复的元素,接收一个list作为参数 list1=[1,2,3,4] s=set(list1) print(s) #逐个遍历 for i in s: print(i) ...
- PAT Basic 1042
1042 字符统计 请编写程序,找出一段给定文字中出现最频繁的那个英文字母. 输入格式: 输入在一行中给出一个长度不超过 1000 的字符串.字符串由 ASCII 码表中任意可见字符及空格组成,至少包 ...
- leetcode刷题——查找
知识点 备忘-必备算法 题目 顺序查找 二分查找 树表搜索 广度优先搜索算法(BFS) 深度优先搜索算法(DFS) 回溯(Backtracking) 题解 CS-Notes Algorithm_Int ...
- 关于Powershell执行时的问题
问题1: [问题描述] 使用Invoke-Command命令登录远程主机执行命令时,提示如下错误: [192.168.1.135] 连接到远程服务器失败,错误消息如下: WinRM 客户端无法处理该请 ...
- Knockout v3.4.0 中文版教程-2-监控-通过监控创建视图模型(上)
2. 监控 1.通过监控创建视图模型 1. 监控 Knockout是基于以下三个核心特性: 监控和依赖跟踪 声明式绑定 模板 在本节,你将第一次了解这三个特性,在这之前,我们先来了解以下MVVM模式和 ...
- MarkdownPad 2 HTML 渲染错误解决办法
MarkdownPad 2 HTML 渲染错误解决办法 1. 安装SDK工具包 Awesomium 1.6.6 SDK 2. 安装渲染插件Microsoft’s DirectX End-User Ru ...