`
gaotong1991
  • 浏览: 92978 次
  • 来自: 北京
社区版块
存档分类
最新评论

快慢指针在链表中的应用

阅读更多

快慢指针也是面试中的一个常考知识点,主要是链表的问题中应用较多。

1. 判断链表是否存在环

设置两个指针(fast, slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。(当然,fast先行头到尾部为NULL,则为无环链表)程序如下:

01 int isExitsLoop(LinkList L) {
02 LinkList fast, slow;
03 fast = slow = L;
04 while (fast && fast->next)
05 {
06 slow = slow->next;
07 fast = fast->next->next;
08 if (slow == fast)
09 {
10 break;
11 }
12 }
13 return ((fast == NULL) || (fast->next == NULL));
14 }

找到环的入口点

当fast若与slow相遇时,slow肯定没有走遍历完链表,而fast已经在环内循环了n圈(1<=n)。假设slow走了s步,则fast走了2s步(fast步数还等于s 加上在环上多转的n圈),设环长为r,则:

1 2s = s + nr
2 s= nr

设整个链表长L,入口环与相遇点距离为x,起点到环入口点的距离为a。

1 a + x = nr
2 a + x = (n – 1)r +r = (n-1)r + L - a
3 a = (n-1)r + (L – a – x)

(L – a – x)为相遇点到环入口点的距离,由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。程序描述如下:

01 node* findLoopPort(node *head) {
02 node *fast, *slow;
03 fast = slow = head;
04 while (fast && fast->next) {
05 slow = slow->next;
06 fast = fast->next->next;
07 if (slow == fast) {
08 break;
09 }
10 }
11 if ((fast == NULL) || (fast->next == NULL)) {
12 return NULL;
13 }
14 slow = head;
15 while (slow != fast) {
16 slow = slow->next;
17 fast = fast->next;
18 }
19 return slow;
20 }

如何快速找出未知长度单链表的中间节点?

普通方法:先遍历一遍单链表确定其长度L后,再从头节点出发循环L/2次即可查找到单链表的中间节点。该问题如果采用普通的方法虽然简单,但是查找效率太低。

快慢指针: 设置两个指针*fast、*slow都指向单链表的头节点,其中*fast的移动速度是*slow的2倍,当*fast指向末尾节点的时候,slow正好就在中间了,可以大大提高查找的效率。

当然,此时算法 还要考虑链表结点个数的奇偶数因素,当快指针移动x次后到达表尾(1+2x),说明链表有奇数个结点,直接返回慢指针指向的数据即可。如果快指针是倒数第二个结点,说明链表结点个数是偶数,这时 可以 实际情况 返回上中位数或下中位数或(上中位数+下中位数)的一半。

这个应用实际在前面讲到的对链表进行排序有用过。

参考 :http://www.acmerblog.com/fast-slow-pointer-5382.html

分享到:
评论

相关推荐

    快慢指针判断链表是否有环-go 语言实现

    在这个例子中,我们首先定义了一个链表节点 ListNode,然后实现了 hasCycle 函数,它接受链表头节点 head 作为参数。函数内部,我们使用两个指针 slow...在实际应用中,确保链表节点的 Next 指针正确设置是非常重要的。

    快慢指针证明带环单链表

    快慢指针是一种常用的算法技巧,在链表中有环的情况下特别有效。该方法的核心思想是利用两个速度不同的指针(通常一个快指针每次移动两个节点,一个慢指针每次移动一个节点)来判断链表中是否存在环。 - **慢指针**...

    面试题快慢链表和快慢指针

    快慢链表和快慢指针在面试中的应用 快慢链表和快慢指针是一种常见的数据结构和算法设计模式,广泛应用于各种面试题中,例如腾讯的一道面试题:如何快速找到位置长度单链表的中间节点?本文将详细介绍快慢链表和快慢...

    快慢指针法判断链表是否有环-go语言实现

    我们首先定义了一个链表节点 ListNode,然后实现了 hasCycle 函数,它接受链表头节点 head 作为参数。函数内部,我们使用两个指针 slow 和 fast,slow...在实际应用中,确保链表节点的 Next 指针正确设置是非常重要的。

    快慢指针法的leetcode题目绘制

    这种方法在LeetCode等编程挑战平台上广泛应用,能够高效地解决链表中的循环、反转等问题。 首先,我们来看141. 环形链表。这个题目要求判断一个链表是否存在环。快慢指针在这里的使用非常直观:快指针每次移动两格...

    leetcode-链表笔记

    - **快慢指针**:在查找环和确定链表中间节点时,使用快慢指针可以有效解决问题。 - **双指针**:在合并链表或查找特定节点时,两个指针可以同步进行不同操作。 5. **链表的应用场景** - 在数据库中,B树和B+树...

    RE_链表1

    这可以通过快慢指针找到链表中点,然后逆序后半部分并进行交替合并实现。 最后,【Q148 排序链表】要求使用链表的归并排序算法。由于链表不能像数组那样方便地进行随机访问,我们不能直接使用快速排序。因此,选择...

    链表的19种算法(C语言)

    15. **链表中位数**:找出链表的中间节点,可以采用快慢指针,也可以先排序再取中间。 16. **按顺序交替合并两个链表**:将两个链表的节点交替插入新的链表中,如1-&gt;2-&gt;1-&gt;2-&gt;...。 17. **删除倒数第k个节点**:...

    用C++实现的循环链表

    在普通链表中,我们可以用快慢指针(龟兔赛跑法)来判断,但循环链表中则无需额外的判断,因为循环的特性使得快慢指针最终总会相遇。 为了实现这些操作,我们可以编写一系列成员函数,包括构造函数、析构函数、插入...

    实验二 链表基本操作的实现

    在实际应用中,链表常用于动态内存管理、数据库索引、实现堆栈和队列等场景。 在实验二的文件中,你可能会找到一些示例代码、练习题目以及解决方案,这些都是帮助你掌握链表操作的好资源。确保理解每行代码的功能,...

    C例子:循环链表

    一种解决方案是使用快慢指针,慢指针每次移动一个节点,快指针每次移动两个节点,当快指针再次追上慢指针时,链表的长度就是快指针移动的步数除以2。 10. **内存管理**: 在操作链表的过程中,必须注意正确地分配...

    链表深度解析:从基础到高级算法

    讲解了双指针技术在解决链表问题中的应用,包括快慢指针等策略。 列出了使用双指针技术的经典链表题目,帮助读者通过实际问题学习双指针技巧。 本章内容适合编程爱好者和专业人士学习和复习链表相关知识,通过结合...

    编程判断两个链表是否相交

    具体地,在将两个链表拼接后,使用快慢指针从第二个链表的头部出发,如果最终快慢指针相遇,则说明存在环,进而说明两个链表相交;反之,不存在环,则不相交。对于解法四,也可以通过快慢指针的方法来判断链表是否...

    算法链表.docx

    链表是一种基础且重要的数据结构,它在计算机科学中被广泛应用。本文将深入探讨链表的几个关键操作:链表反转、合并有序列表、新增节点、删除节点、判断链表是否有环以及找到链表的中间节点。我们将使用Java语言进行...

    判断单链表中是否存在环

    这种结构如果在实际应用中没有被正确处理,可能会导致程序无限循环,消耗大量系统资源,甚至引发程序崩溃。 ### 解决方案:快慢指针法 针对判断单链表中是否存在环的问题,最常用的解决方案是使用“快慢指针”技术...

    c语言编程题之链表操作链表的中间节点.zip

    在这个示例中,`findMiddle` 函数接收链表的头节点作为参数,通过快慢指针找到中间节点并返回。在 `main` 函数中,我们创建了一个链表,然后调用 `findMiddle` 函数找到中间节点,并打印出它的值。 链表操作在C语言...

    python 教程 leetcode 代码模板-Linked-List-Two-Pointers.md

    #### 二、快慢指针在链表中的应用 链表中常用的双指针技术有两种:“快慢指针”与“分离双指针”。其中,“快慢指针”根据起点是否一致以及步长是否相同进一步细分为“起点不一致的快慢指针”和“步长不一致的快慢...

    双指针算法 使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的

    在实际应用中,双指针能帮助我们更高效地遍历数据结构,解决问题。 在设计双指针算法时,关键在于选择合适的速度和初始位置,以及正确处理指针间的交互。对于相同方向的双指针,通常一个指针移动得较快,而另一个较...

    js代码-5.1 删除链表倒数第n个节点 快慢指针

    在实际应用中,这段代码可以很好地处理各种情况,包括链表为空、n等于链表长度、n大于链表长度等。通过使用快慢指针,我们可以在一次遍历中解决问题,时间复杂度为O(n),空间复杂度为O(1),效率较高。在`main.js`...

    js代码-2.14 定位环的起点(flag+快慢指针)

    6. **注意事项**:提醒用户如何处理无环链表,以及在实际应用中可能出现的特殊情况。 通过理解和实践这段代码,开发者可以掌握如何在JavaScript中检测链表环,并找到环的起点,这对于解决数据结构和算法问题,尤其...

Global site tag (gtag.js) - Google Analytics