代码改变世界

深入解析:C++ 双指针:从原理到实战的全面解析

2026-01-25 11:36  tlnshuju  阅读(7)  评论(0)    收藏  举报

双指针是 C++ 中高效解决数组、链表等线性数据结构问题的核心技巧,依据维护两个指针协同遍历,能将暴力解法的 O (n²) 时间复杂度优化至 O (n),大幅提升代码效率。

一、双指针的核心原理

双指针本质是利用两个指针(可理解为指向数据结构元素的索引或指针变量),根据问题逻辑同步或异步移动,减少不必要的遍历操作。其核心优势在于 “用空间换时间”,通过额外的指针变量,将嵌套循环转化为单层循环。

1. 指针的本质

在 C++ 中,双指针的载体分两种场景:

  • 数组 / 字符串场景:指针通常是int类型的索引(如ij),指向数组元素的下标。
  • 链表场景:指针是ListNode*类型的指针变量(如slowfast),直接指向链表节点。

2. 核心思想

双指针借助 “分工协作” 实现高效遍历:

  • 一个指针负责 “探索”(如遍历所有元素),另一个指针负责 “记录”(如标记目标位置、维护窗口边界)。
  • 避免对同一元素的重复检查,例如在 “两数之和” 问题中,无需嵌套遍历所有元素对,只需通过指针移动匹配目标值。

二、双指针的三大经典类型

根据指针的移动方向和起始位置,双指针可分为三类,不同类型对应不同的问题场景,需针对性选择。

1. 同向双指针(快慢指针)

定义:两个指针从同一端(通常是起始位置)出发,以不同速度同向移动,快指针遍历数据,慢指针维护目标区间或结果。适用场景:数组去重、链表环检测、滑动窗口(固定窗口大小)等。核心逻辑:快指针先行,满足条件时慢指针再移动,两者形成 “追赶” 关系。

实战案例:移除数组中的重复元素

题目要求:在非严格递增数组中,原地删除重复元素,返回新数组长度(LeetCode 26)。

#include <vector>
  using namespace std;
  int removeDuplicates(vector<int>& nums) {
    
    if (nums.empty()) return 0; // 边界条件:空数组直接返回0
    int slow = 0; // 慢指针:标记不重复元素的最后位置
    // 快指针:遍历所有元素,寻找不重复值
    for (int fast = 1; fast < nums.size(); fast++) {
    
    // 当快指针找到与慢指针不同的值时,慢指针前移并更新值
    if (nums[fast] != nums[slow]) {
    
    slow++;
    nums[slow] = nums[fast];
    }
    }
    return slow + 1;