跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

双指针算法初阶详解:移动零与复写零

双指针算法包含对撞指针与快慢指针两种模式,常用于数组或链表处理。针对移动零问题,利用快慢指针将非零元素前置并补零;针对复写零问题,先计算有效长度后倒序遍历填充。示例提供 C++ 原地操作方案,确保空间复杂度为 O(1),避免额外数组分配。

黑客发布于 2026/3/28更新于 2026/6/1227 浏览
双指针算法初阶详解:移动零与复写零

双指针算法简介

双指针算法是算法题中常见的一种技巧,主要分为对撞指针和快慢指针。

对撞指针

一般用于顺序结构,也叫左右指针。

实现思路:

  1. 对撞指针从序列两端向中间移动。
  2. 终止条件一般为两个指针相遇或错开。

快慢指针

又称龟兔赛跑算法,使用两个移动速度不同的指针在序列上移动,常用于环形链表或数组。

实现思路:

  1. 研究问题是否存在循环往复现象。
  2. 设置快指针和慢指针,例如快指针移动两步,慢指针移动一步。

相关例题

移动零

题目描述

给定一个数组 nums,编写一个函数将所有 0 移动到数组末尾,同时保持非零元素的相对顺序。必须在不复制数组的情况下原地对数组进行操作。

示例 1:

cpp
输入:nums = [0,1,0,3,12]
输出:[1,3,12,0,0]

示例 2:

cpp
输入:nums = [0]
输出:[0]

提示:

  • 1 <= nums.length <= 10^4
  • -2^31 <= nums[i] <= 2^31 - 1

进阶: 尽量减少完成的操作次数。

实现思路

本质是将非零数放在数组开头且顺序不变,零放在尾端。标准的双指针解法如下:

  1. 初始化两个指针 cur 用于扫描数组,dest 用于记录非零序列的最后一个位置。
  2. 遍历时 [0, dest] 的元素为非零元素,[dest - 1, cur - 1] 的元素为零元素。
  3. 若遇到非零数,则 ++dest 并交换 cur 位置和 dest 位置。

实现代码:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int n = nums.size();
        int index = -1;
        for (int i = 0; i < n; ++i) {
            if (nums[i]) {
                swap(nums[++index], nums[i]);
            }
        }
    }
};

复写零

题目描述

给你一个长度固定的整数数组 arr,将该数组中出现的每个零都复写一遍,并将其余元素向右平移。注意不要超过该数组长度的位置写入元素。请就地修改,不返回任何东西。

示例 1:

cpp
输入:arr = [1,0,2,3,0,4,5,0]
输出:[1,0,0,2,3,0,0,4]

示例 2:

cpp
输入:arr = [1,2,3]
输出:[1,2,3]

提示:

  • 1 <= arr.length <= 10^4
  • 0 <= arr[i] <= 9
实现思路

需要判断特殊情况,找到复写后数组的最后一个元素复写前的下标。

  1. 使用双指针遍历,确定最后一个可复写的值的位置。
  2. 根据是否越界决定是从前往后还是从后往前填充。
  3. 从后往前遍历数组进行复写操作,遇到零则写入两个零。

实现代码:

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        int cur = 0, dest = -1, s = arr.size();
        while (cur < s) {
            if (arr[cur]) dest++;
            else dest += 2;
            if (dest >= s - 1) break;
            cur++;
        }
        if (dest == s) {
            arr[s - 1] = 0;
            dest -= 2;
            cur--;
        }
        while (cur >= 0) {
            if (arr[cur]) arr[dest--] = arr[cur--];
            else {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
        }
    }
};

目录

  1. 双指针算法简介
  2. 对撞指针
  3. 快慢指针
  4. 相关例题
  5. 移动零
  6. 题目描述
  7. 实现思路
  8. 复写零
  9. 题目描述
  10. 实现思路
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 大模型应用:如何增强模型记忆力与上下文管理
  • 二叉树、平衡树、B 树与 B+ 树核心原理及代码实现
  • OpenClaw 安装与配置百度网页搜索技能
  • 滑动窗口算法实战:找到字符串中所有字母异位词
  • SpringBoot 结合 RabbitMQ 实现应用间通信详解
  • Anaconda 环境变量配置意义及捆绑 Python 路径说明
  • node-llama-cpp 错误处理与调试:解决本地 AI 开发常见问题
  • 为什么从 C# 转 Java 开发时常有落差感
  • CentOS 7 安装 MySQL 5.7 失败记录
  • LLM 存储优化实战:解决大量 QA 与长对话记忆问题
  • 同花顺 API 收费模式与档位选择指南
  • 深入理解 MySQL 索引:核心原理与实战优化指南
  • Microsoft Visual C++ 运行库安装与 DLL 缺失修复指南
  • Ubuntu 安装 MySQL 社区版
  • MySQL mysqldump 导入导出结构与数据及存储过程函数事件触发器
  • MySQL 数据库基础与核心概念详解
  • MySQL 8.0.0 开发里程碑版本发布
  • Git 零基础实战:Vscode + 码云配置与操作指南
  • Linux 进程状态详解
  • SpringBoot 配置文件详解:Properties 与 YML 格式对比

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online