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

双指针算法精解:对撞指针与快慢指针的妙用与实践

目录

一、对撞指针(Colliding Pointers)

1.细节

2.思想

3.功能

4.代码示例

二、左右指针(快慢指针,Slow-Fast Pointers)

1.细节

2.思想

3.功能

4.代码示例

三、总结


一、对撞指针(Colliding Pointers)

1.细节

  • 定义:对撞指针使用两个指针,一个从数组的起始位置(左指针)开始,另一个从数组的末尾(右指针)开始,两个指针向中间移动,直到相遇或交叉。

  • 适用场景:通常用于有序数组或可以通过排序转化为有序数组的问题。

  • 时间复杂度:O(n),因为每个指针最多遍历数组一次。

2.思想

  • 核心思想:通过左右指针的协同移动,缩小问题的搜索范围。利用数组的有序性,通过比较指针指向的值与目标值的关系,决定移动哪个指针。

  • 优势:避免了暴力搜索的高时间复杂度(O(n^2)),将问题优化为线性时间复杂度。

3.功能

  • 典型应用

    1. 两数之和:在有序数组中找到两个数,使它们的和等于目标值。

    2. 三数之和:找到数组中三个数,使它们的和等于目标值。

    3. 回文串判断:判断一个字符串是否为回文串。

4.代码示例

#include <vector>
#include <algorithm>

// 两数之和问题
std::vector<int> twoSum(std::vector<int>& nums, int target) 
{
    std::sort(nums.begin(), nums.end()); // 首先对数组排序
    int left = 0;
    int right = nums.size() - 1;
    while (left < right) 
    {
        int sum = nums[left] + nums[right];
        if (sum == target) 
        {
            return {nums[left], nums[right]}; // 返回找到的两个数
        } 
        else if (sum < target) 
        {
            left++; // 和小于目标值,左指针右移
        } 
        else 
        {
            right--; // 和大于目标值,右指针左移
        }
    }
    return {}; // 如果没有找到,返回空数组
}

二、左右指针(快慢指针,Slow-Fast Pointers)

1.细节

  • 定义:快慢指针使用两个指针,一个移动速度快(快指针),另一个移动速度慢(慢指针)。通常快指针每次移动两步,慢指针每次移动一步。

  • 适用场景:常用于链表数组中的循环检测、中点查找、滑动窗口等问题。

  • 时间复杂度:O(n),因为每个指针最多遍历链表或数组一次。

2.思想

  • 核心思想:通过快慢指针的速度差,解决一些需要定位特定位置或检测特定模式的问题。例如,快指针的速度是慢指针的两倍,可以用来找到链表的中点或检测环。

  • 优势:避免了额外的空间开销(如使用哈希表),同时保持线性时间复杂度。

3.功能

  • 典型应用

    1. 链表环检测:判断链表中是否存在环。

    2. 链表中点查找:找到链表的中点。

    3. 滑动窗口:解决子数组或子字符串的相关问题。

4.代码示例

#include <iostream>

struct ListNode 
{
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

// 链表环检测
bool hasCycle(ListNode* head) 
{
    if (head == nullptr || head->next == nullptr) 
    {
        return false;
    }
    ListNode* slow = head; // 慢指针
    ListNode* fast = head; // 快指针
    while (fast != nullptr && fast->next != nullptr) 
    {
        slow = slow->next; // 慢指针每次移动一步
        fast = fast->next->next; // 快指针每次移动两步
        if (slow == fast) 
        {
            return true; // 快慢指针相遇,说明有环
        }
    }
    return false; // 无环
}

// 链表中点查找
ListNode* findMiddle(ListNode* head) 
{
    ListNode* slow = head;
    ListNode* fast = head;
    while (fast != nullptr && fast->next != nullptr) 
    {
        slow = slow->next; // 慢指针每次移动一步
        fast = fast->next->next; // 快指针每次移动两步
    }
    return slow; // 慢指针指向中点
}

三、总结

类型细节思想功能
对撞指针两个指针从两端向中间移动,适用于有序数组。利用有序性缩小搜索范围,优化时间复杂度。两数之和、三数之和、回文串判断等。
左右指针快慢指针以不同速度移动,适用于链表或数组。通过速度差定位特定位置或检测特定模式。链表环检测、链表中点查找、滑动窗口等。

        双指针技术是一种非常实用的算法设计思想,能够有效解决许多经典问题。掌握对撞指针和左右指针的使用场景和实现细节,可以显著提升算法能力。 


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

相关文章:

  • ios swift画中画技术尝试
  • 36、【OS】【Nuttx】OSTest分析(2):环境变量测试
  • 05-机器学习-数据标注
  • XSS 漏洞全面解析:原理、危害与防范
  • 探秘 TCP TLP:从背景到实现
  • C语言基础3
  • 2025年大数据毕业设计选题推荐:数据分析与可视化 数据挖掘
  • 获取metadata耗时对比(libtag/ffmpeg/gstreamer)
  • 第 5 章:声音与音乐系统
  • 一文大白话讲清楚webpack基本使用——17——Tree Shaking
  • [Dialog屏幕开发] 屏幕绘制(使用向导创建Tabstrip Control标签条控件)
  • Java 9模块开发:IntelliJ IDEA实战指南
  • Transformation,Animation and Viewing
  • 高通Yocto项目 - 全解析
  • 【MQ】探索 Kafka
  • 【Unity3D】Unity混淆工具Obfuscator使用
  • 51单片机入门_01_单片机(MCU)概述(使用STC89C52芯片;使用到的硬件及课程安排)
  • PAT甲级-1022 Digital Libiary
  • Python JSON:深入解析与高效应用
  • 21.Word:小赵-毕业论文排版❗【39】
  • PHP 7 新特性
  • JAVA实战开源项目:蜗牛兼职平台(Vue+SpringBoot) 附源码
  • 数论问题74
  • Linux C++
  • 「Unity3D」在Unity中使用C#控制显示Android的状态栏
  • 02数组+字符串+滑动窗口+前缀和与差分+双指针(D5_双指针)