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

LeetCode 原地复写零:双指针与逆向填充 O(n) 时间 O(1) 空间解法

LeetCode 原地复写零问题要求在固定长度数组中复写每个 0 并右移其余元素,且需满足原地修改、不使用额外数组空间的约束。正向遍历易导致后续元素被覆盖,采用双指针配合逆向填充策略可高效解决。首先通过双指针定位最后一个需要复写的元素边界,处理边界情况后从后向前遍历数组进行填充。该方案实现了 O(n) 线性时间复杂度与 O(1) 常数空间复杂度的最优表现,是解决数组原地修改类问题的关键技巧。

flc发布于 2026/3/26更新于 2026/9/1164 浏览
LeetCode 原地复写零:双指针与逆向填充 O(n) 时间 O(1) 空间解法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

一、复写零

在这里插入图片描述

二、思路分析

复写零这道题是让在原数组修改,如果从前向后遍历,后面的元素会被覆盖,所以我们要找到被复写的最后一个元素,然后从后往前复写。运用双指针 + 逆向填充。

1. 找到复写的最后一个数

定义两个指针:cur 遍历原数组,pre 模拟复写后的数组指针;cur==0 时,pre 向后移动两位,cur!=0 时,pre 向后移动一位(逻辑上对应复写后的位置);当 pre>=n-1 时,停止遍历,这时,cur 指的就是要复写的最后一个元素。

在这里插入图片描述

边界情况:如下面这种情况,pre == n 时,说明要复写的最后一个元素是 0,这里单独处理。

将数组最后一位改为 0,也就是 n==0;cur 向前移动一位,pre 向前移动两位。

在这里插入图片描述

2. 开始从后往前复写

从 cur 向前遍历,cur != 0 时,就让 arr[pre] == arr[cur]; cur == 0 时,就让 pre 和 pre-1 位置的数都改为 0,然后继续向前复写。

在这里插入图片描述

三、代码展示

class Solution {
    public void duplicateZeros(int[] arr) {
        int cur = 0, pre = -1, n = arr.length;
        // 1. 找到要复写的最后一个元素
        while (cur < n) {
            if (arr[cur] == 0) {
                pre += 2;
            } else {
                pre++;
            }
            if (pre >= n - 1) {
                break;
            }
            cur++;
        }
        // 处理边界情况
        if (pre == n) {
            arr[n - 1] = 0;
            cur--;
            pre -= 2;
        }
        // 开始从后向前复写
        while (cur >= 0) {
            if (arr[cur] != 0) {
                arr[pre--] = arr[cur--];
            } else {
                arr[pre--] = 0;
                arr[pre--] = 0;
                cur--;
            }
        }
    }
}

四、时间和空间复杂度分析

  • 时间复杂度 O(n):只需要遍历数组两次,第一次定位边界,第二次逆向填充;
  • 空间复杂度 O(1): 使用的原数组,没有额外空间

五、总结

本解法通过双指针先定位复写边界,再逆向填充数组,既避免了正向遍历的元素覆盖问题,又实现了 O(n) 线性时间复杂度与 O(1) 常数空间复杂度的最优表现。其中'先确定边界、再逆向操作'的思路,是解决数组原地修改类问题的关键技巧,具有较强的通用性与实用性。

在这里插入图片描述

目录

  1. 一、复写零
  2. 二、思路分析
  3. 1. 找到复写的最后一个数
  4. 2. 开始从后往前复写
  5. 三、代码展示
  6. 四、时间和空间复杂度分析
  7. 五、总结

更多推荐文章

查看全部
  • Llama-Factory 微调模型上线前的 A/B 测试实践
  • MCP 教程:将 Figma 设计稿转化为前端代码
  • 大模型核心面试题与关键技术解析
  • llama.cpp 实战指南:在普通 CPU 上运行大模型
  • PyTorch 安装适配 Stable Diffusion 3.5 FP8 指南
  • 使用 Docker 在 Ubuntu 虚拟机中安装 OpenClaw
  • AI 机器人安全私信访问机制:Secure DM Pairing 实现原理
  • 前端 HTML 转 Word 文档:html-docx-js 实战指南
  • Topaz Photo AI v1.3.3 汉化便携版:图片降噪与无损放大工具
  • LLM 局限性解析与 LangChain 框架初探
  • JS获取IP、MAC和主机名的几种方法 .
  • CLAUDE.md 与 AGENTS.md 配置指南:让 AI 编程助手更懂你的项目
  • GitHub Copilot 代理配置与网络优化实战指南
  • 中小型火电厂机器人巡检系统经济高效部署指南
  • 零成本搭建飞书机器人:利用 Webhook 实现消息推送
  • 利用闲置 Mac Mini 部署 OpenClaw 构建本地金融 AI 助手
  • MAC 地址简介及 Windows 系统查看方法
  • FPGA:重构硬件逻辑的柔性算力核心,国产替代的破局关键
  • FPGA 图像处理:图像畸变矫正原理及 MATLAB 与 FPGA 实现
  • 2025 年 10 大 AI 模型 API 中转聚合平台横评与选型指南

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

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

  • Gemini 图片去水印

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