跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C算法

双指针算法实战:移动零与复写零详解

通过移动零和复写零两道经典算法题,深入讲解双指针技巧在数组操作中的应用。移动零采用前后指针交换法实现原地去零;复写零则利用从后向前遍历避免数据覆盖问题。内容包含详细思路解析与 C 语言代码实现,适合希望巩固基础算法的开发者阅读。

热情发布于 2026/3/21更新于 2026/5/45 浏览
双指针算法实战:移动零与复写零详解

在学习了基础语法之后,是时候通过实战来巩固一下双指针技巧了。今天我们来搞定两道经典的数组操作题:移动零和复写零。

一、移动零

题目描述

给定一个数组 nums,要求将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。注意:必须在原数组上操作,不能创建新数组。

思路解析

这道题的核心在于如何原地交换。很多人第一反应是新建一个数组存非零元素,但这违反了空间复杂度的要求。

我们可以使用两个指针:

  • cur(current):负责遍历整个数组,寻找非零元素。
  • dest(destination):指向当前应该放置非零元素的位置。

当 cur 遇到非零元素时,将其与 dest 位置的元素交换,然后 dest 后移。如果 cur 遇到的是 0,则跳过,继续向后找。这样能保证所有非零元素按顺序前移,剩下的位置自然就是 0。

这里有个小细节:如果 cur 和 dest 指向同一个位置,其实不需要交换,直接跳过即可,能减少不必要的内存写入。

代码实现

void Swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

void moveZeroes(int* nums, int numsSize) {
    int cur = 0;
    int dest = 0;
    while (cur < numsSize) {
        if (nums[cur] != 0) {
            // 只有当两个指针不重合时才交换,优化性能
            if (cur != dest) {
                Swap(&nums[dest], &nums[cur]);
            }
            dest++;
        }
        cur++;
    }
}

这段代码在力扣平台上运行效率不错,逻辑清晰且符合原地修改的要求。

二、复写零

题目描述

在一个固定长度的整数数组中,将每个出现的 0 重复一遍。数组后面的元素会被覆盖掉,不需要保留。

思路解析

这道题如果从前向后处理会非常麻烦。因为一旦你在中间插入了一个 0,后面的元素都要往后挪一位,这会导致已经处理过的数据被覆盖或者需要频繁移动内存,复杂度很高。

最佳策略是从后向前遍历。

  1. 统计范围:先遍历一遍数组,算出如果进行复写操作,最终的有效长度会延伸到哪里。我们需要找到最后一个会被写入的元素位置。
  • 边界判断:如果扩展后的长度超过了原数组大小,说明最后一个 0 无法完整复写(只能写一个),需要特殊处理边界情况。
  • 倒序填充:从后往前,遇到非 0 就拷贝,遇到 0 就写两次 0。
  • 这样做的好处是,我们不会覆盖掉还没处理的数据,因为我们是往空出来的位置写。

    代码实现

    void duplicateZeros(int* arr, int arrSize) {
        int cur = 0;
        int dest = -1;
        
        // 第一步:计算复写后的有效索引
        while (cur < arrSize) {
            if (arr[cur]) {
                dest++;
            } else {
                dest += 2;
            }
            if (dest >= arrSize - 1) break;
            cur++;
        }
        
        // 第二步:处理边界情况
        // 如果 dest 刚好等于 arrSize,说明最后一个元素是 0,但只能写一次
        if (dest == arrSize) {
            arr[arrSize - 1] = 0;
            cur--;
            dest -= 2;
        }
        
        // 第三步:从后向前填充
        while (cur >= 0) {
            if (arr[cur]) {
                arr[dest] = arr[cur];
            } else {
                arr[dest] = 0;
                arr[dest - 1] = 0;
                dest--;
            }
            dest--;
            cur--;
        }
    }
    

    提交到平台验证,逻辑完全正确。这两道题虽然简单,但很好地体现了双指针在不同场景下的应用差异,值得反复琢磨。

    目录

    1. 一、移动零
    2. 题目描述
    3. 思路解析
    4. 代码实现
    5. 二、复写零
    6. 题目描述
    7. 思路解析
    8. 代码实现
    • 💰 8折买阿里云服务器限时8折了解详情
    • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
    • 代充Chatgpt Plus/pro 帐号了解详情
    • 🤖 一键搭建Deepseek满血版了解详情
    • 一键打造专属AI 智能体了解详情
    极客日志微信公众号二维码

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

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

    更多推荐文章

    查看全部
    • 2024 年十大高效 AI 办公与学习工具推荐
    • 学术论文知网 AIGC 检测原理与降重实操指南
    • 知网 AIGC 检测原理与论文降重实操指南
    • C++26 并发编程新特性:任务队列容量优化
    • HBase 核心架构解析:HMaster、RegionServer 与 ZooKeeper 协同机制
    • HBase 架构深度解析:HMaster、RegionServer 与 ZooKeeper 协同机制
    • 基于腾讯云服务器、宝塔面板与 Nginx 部署云图库项目
    • 旋转矩阵、齐次变换矩阵、欧拉角与四元数相互转换 C++ Python 实现
    • C++ 多态底层实现原理与内存布局解析
    • C++ 多态底层实现原理:虚表、虚指针与内存布局
    • DeepSeek-R1-Distill-Llama-8B 在线演示与能力实测
    • VS Code Copilot Chat 扩展调试指南:快速解决运行问题
    • 飞算 JavaAI 专业版深度测评:AI 工具箱助力 Java 开发与项目管理
    • MyBatisPlus 与 Thymeleaf 全栈分页整合方案
    • 智能家居安全摄像头对比:Ring与Blink全面解析
    • MySQL 基本查询详解:增删查改核心语法实战
    • 智能家居 AI 开发指南:树莓派与云端 GPU 混合方案
    • nanobind C++/Python 高性能绑定实战指南
    • Linux 下 Vim 编辑器使用详解
    • C# 调用豆包 AI 模型实现首尾帧视频生成

    相关免费在线工具

    • 加密/解密文本

      使用加密算法(如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