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

算法基础:双指针技巧解决移动零问题

双指针算法通过维护读写指针实现原地操作。本文详解移动零问题的解决方案,利用快慢指针交换非零元素至前端,保持相对顺序。同时拓展至三指针分区思想,简述其在颜色分类及快速选择中的应用场景,提供 Java 代码实现与核心逻辑解析。

1951018925发布于 2026/3/15更新于 2026/10/2696 浏览
算法基础:双指针技巧解决移动零问题

题目背景

在 LeetCode 283 题「移动零」中,给定一个数组 nums,要求将所有 0 移动到数组末尾,同时保持非零元素的相对顺序。关键约束是必须原地操作,不能复制数组。

示例:

  • 输入:[0,1,0,3,12]
  • 输出:[1,3,12,0,0]

双指针核心思路

处理这类'原地重排'问题的经典方法是使用双指针。我们可以将指针分为两个角色:

  1. 遍历指针 (cur):负责扫描整个数组,寻找符合条件的元素(非零数)。
  2. 维护指针 (dest):指向当前已整理好的非零序列的末尾位置。

具体逻辑如下:

  • 初始化 dest = -1,表示尚未发现任何非零元素。
  • cur 从头开始遍历。
  • 当 nums[cur] 不为 0 时,说明找到了一个需要保留的元素。此时先将 dest 向前移动一位,然后将 nums[cur] 与 nums[dest] 交换。
  • 如果 dest 恰好等于 cur,交换相当于自身赋值,不影响结果;如果不等,则实现了将非零元素'冒泡'到左侧的效果。

这种写法避免了额外的空间开销,时间复杂度为 O(n),空间复杂度为 O(1)。

拓展:三指针与分区思想

双指针的本质是对数组进行分区。当我们面对更复杂的条件时,可以引入第三个指针来维护中间区域,这就是三指针原理的典型应用。

以 LeetCode 75 题「颜色分类」为例,需要将数组按 0、1、2 排序。这可以通过类似快速排序的分区思想实现:

  • 左块:小于基准值(如 0)
  • 中块:等于基准值
  • 右块:大于基准值

通过三个指针分别维护这三块的边界,可以在一次遍历内完成排序。这种分区策略不仅适用于颜色分类,也是快速选择算法(Quick Select)和快速排序(Quick Sort)的基础。虽然这些算法的具体实现细节有所不同,但核心都在于利用指针高效地划分数据范围。

代码实现

下面是基于上述思路的 Java 实现。代码中保留了详细的注释,方便理解每一步的意图。

public void moveZeroes(int[] nums) {
    int cur = 0;      // 遍历指针,扫描整个数组
    int dest = -1;    // 维护指针,记录最后一个非零元素的位置
    
    while (cur < nums.length) {
        if (nums[cur] != 0) {
            // 找到非零元素,先移动维护指针
            dest++;
            // 交换当前元素与维护指针位置的元素
            // 若 dest == cur,相当于自交换,无副作用
            int tmp = nums[dest];
            nums[dest] = nums[cur];
            nums[cur] = tmp;
        }
        cur++;
    }
}

在实际运行中,你会发现这个逻辑非常稳健。即使数组全为 0 或全为非 0,逻辑依然成立。关键在于 dest 始终指向'下一个应该放置非零元素的位置',而 cur 负责确认当前位置是否满足条件。

目录

  1. 题目背景
  2. 双指针核心思路
  3. 拓展:三指针与分区思想
  4. 代码实现

更多推荐文章

查看全部
  • Pi0 机器人大模型在昇腾 A2 平台上的部署与性能测评
  • AR/VR 与边缘计算融合下的测试扩展策略
  • Faster Whisper 语音识别工具安装与性能优化指南
  • Docker 部署 OpenClaw 并集成智谱 AI
  • Linux 线程与进程深度剖析:虚实内存转换、实现机制与优缺点
  • C++ 哈希表核心改造与 unordered_set、unordered_map 封装实现
  • 从 Copilot 到 Agent:构建私有化开发助手指南
  • Windows 系统 Python 版本管理工具 pyenv-win
  • 纯 QWidget 实现电子地图控件:多线程瓦片加载与图形覆盖
  • 小红书 AlignRec: 多模态推荐系统的对齐与训练框架
  • C++ 继承机制核心解析
  • Flutter wasm_interop 鸿蒙 Web 端适配与高性能计算实战
  • Mac 系统唤醒增强工具 Amphetamine Enhancer 使用指南
  • Claude Code 源码因 Source Map 配置失误泄露,51 万行代码公开
  • RAG 中的融合检索与递归检索
  • OpenClaw 全平台卸载指南:Windows、macOS、Linux 与包管理器
  • DeepSeek-R1-Distill-Llama-70B 蒸馏模型推理能力与技术分析
  • Windows 安装 Python 后 CMD 命令行无法识别
  • AgentScope-Java 框架特性及快速入门
  • 机器人运动学:标准 DH 与改进 DH 参数对比

相关免费在线工具

  • 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