当前位置: 首页 > article >正文

快慢指针:链表问题的利器

快慢指针:链表问题的利器

1. 快慢指针的基本概念

快慢指针是一种双指针技巧,通常用于解决链表问题。它使用两个指针,一个指针(慢指针)每次移动一步,另一个指针(快指针)每次移动两步。通过这种移动方式,快指针的移动速度是慢指针的两倍,因此快指针会先到达链表的末尾。

2. 快慢指针的使用场景

2.1 寻找链表的中间节点

这是快慢指针最常见的应用场景之一。通过快慢指针,可以轻松找到链表的中间节点。当快指针到达链表末尾时,慢指针正好位于链表的中间位置。

示例代码

ListNode *middleNode(ListNode *head) {
    if (head == NULL || head->next == NULL) {
        return head;
    }

    ListNode *fast = head, *slow = head;
    while (fast->next != NULL && fast->next->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }
    if (fast->next != NULL) {
        slow = slow->next;
    }

    return slow;
}

2.2 检测链表中的环

快慢指针也可以用于检测链表中是否存在环。如果链表中存在环,快指针和慢指针最终会在环内相遇。如果快指针到达链表末尾,则链表中不存在环。

示例代码

bool hasCycle(ListNode *head) {
    if (head == NULL || head->next == NULL) {
        return false;
    }

    ListNode *fast = head, *slow = head;
    while (fast->next != NULL && fast->next->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) {
            return true;
        }
    }

    return false;
}

2.3 寻找环的入口

如果链表中存在环,快慢指针还可以用于找到环的入口。当快指针和慢指针在环内相遇后,将其中一个指针重置为链表头,然后两个指针每次各移动一步,它们再次相遇的位置即为环的入口。

示例代码

ListNode *detectCycle(ListNode *head) {
    if (head == NULL || head->next == NULL) {
        return NULL;
    }

    ListNode *fast = head, *slow = head;
    while (fast->next != NULL && fast->next->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast) {
            break;
        }
    }

    if (fast->next == NULL || fast->next->next == NULL) {
        return NULL;
    }

    slow = head;
    while (slow != fast) {
        slow = slow->next;
        fast = fast->next;
    }

    return slow;
}

2.4 寻找链表的倒数第 k 个节点

快慢指针可以用于找到链表的倒数第 k 个节点。首先,将快指针向前移动 k 步,然后快慢指针同时移动,当快指针到达链表末尾时,慢指针正好位于倒数第 k 个节点。

示例代码

ListNode *findKthToLast(ListNode *head, int k) {
    if (head == NULL) {
        return NULL;
    }

    ListNode *fast = head, *slow = head;
    for (int i = 0; i < k; i++) {
        if (fast == NULL) {
            return NULL;
        }
        fast = fast->next;
    }

    while (fast != NULL) {
        slow = slow->next;
        fast = fast->next;
    }

    return slow;
}

3. 快慢指针的优缺点

3.1 优点

  • 高效:快慢指针可以在一次遍历中完成多种任务,时间复杂度通常为 O(n)。
  • 简洁:代码实现简洁,易于理解和维护。
  • 适用广泛:适用于多种链表问题,如寻找中间节点、检测环、找到环的入口等。

3.2 缺点

  • 边界条件复杂:需要仔细处理边界条件,如链表为空、链表长度为 1 等。
  • 指针操作复杂:指针操作容易出错,特别是在处理环和边界条件时。

4. 总结

快慢指针是一种非常实用的链表问题解决技巧,通过合理使用快慢指针,可以高效地解决多种链表问题。掌握快慢指针的使用方法和常见应用场景,将有助于你在算法面试和实际开发中更好地应对链表相关问题。希望本文对你的学习和工作有所帮助。


http://www.kler.cn/a/508414.html

相关文章:

  • 《贪心算法:原理剖析与典型例题精解》
  • 【开源免费】基于SpringBoot+Vue.JS欢迪迈手机商城(JAVA毕业设计)
  • Leetcode3097:或值至少为 K 的最短子数组 II
  • Oracle查询-in条件超过1000
  • ant design vue的级联选择器cascader的悬浮层样式怎么修改
  • Kotlin 协程基础十 —— 协作、互斥锁与共享变量
  • unity免费资源2025-1-17
  • Java合并多个List集合的方法
  • AUTOSAR从入门到精通专栏总目录
  • Linux手写FrameBuffer任意引脚驱动spi屏幕
  • Django多线程爬虫:突破数据抓取瓶颈
  • sparkRDD教程之必会的题目
  • Oracle graph 图数据库体验-安装篇
  • 一文简要了解为什么需要RAG、核心原理与应用场景
  • 陈萍的设计创新:Kevlin Nexus荣获伦敦设计奖,展示品牌设计的国际化与持续创新
  • 【12】Word:张老师学术论文❗
  • 专业130+总分410+西安交通大学815/869原909信号与系统考研电子信息与通信工程。真题,大纲,参考书。
  • 云IDE:开启软件开发的未来篇章
  • 用大白话讲明白JWT
  • Node.js - Express框架
  • Android 实现多语言功能
  • 从零开始:Gitee 仓库创建与 Git 配置指南
  • Temp123
  • 在MyBatis的XML映射文件中,<trim>元素所有场景下的完整使用示例
  • 12.接口和抽象类的区别
  • Python机器学习、深度学习技术提升气象、海洋、水文领域实践应用能力