当前位置: 首页 > news >正文

【双指针专题】之移动零

一、题目描述

给定一个整数数组 nums,将所有的 0 移动到数组末尾,同时保持非零元素的相对顺序。

要求:

  1. 必须 原地操作,不可开辟额外数组。
  2. 要尽量减少不必要的写操作。

示例:

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

这是经典的 双指针问题


二、思路引导:双指针 / 划分思想

把数组想象成两个区域

  • 左侧:已经处理好的 非零区间
  • 右侧:未处理的区间

我们用两个指针

  • cur:扫描数组;
  • dest:非零区间的末尾索引

循环不变式:
在任意时刻,[0..dest] 全是非零元素,且顺序保持;
区间 (dest, cur) 全是零。

每当遇到非零,就把它扩展到非零区间尾部。最终整个数组左边是非零,右边自然就是零


三、标准解法:交换法

下面是直观且常用的写法:

#include <vector>
#include <algorithm>
using namespace std;class Solution {
public:void moveZeroes(vector<int>& nums) {int dest = -1; // 非零区间末尾,初始为 -1for (int cur = 0; cur < (int)nums.size(); ++cur) {if (nums[cur] != 0) {// 遇到非零,就把它放到非零区间末尾++dest;swap(nums[dest], nums[cur]);}}}
};

运行示例:

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

关键步骤:

  • cur=1: 交换 nums[0]nums[1][1,0,0,3,12]
  • cur=3: 交换 nums[1]nums[3][1,3,0,0,12]
  • cur=4: 交换 nums[2]nums[4][1,3,12,0,0]

四、代码剖析与细节问题

1. 为什么 dest 初始为 -1 ?

因为刚开始没有非零区间,赋值 0 不合适,因而赋值 -1 ,这样 ++dest 后第一次正好是 0 

2. swap 的意义?

  • ++dest:先把非零区间末尾向右扩一位;
  • swap(nums[dest], nums[cur]):把当前非零值“放”进去;
  • cur == dest 时,就是自交换。

3. 相对顺序是否保持?

保持,因为我们按顺序依次把非零写到前面。

4. 边界情况:

  • 空数组 → 直接返回;
  • 全 0 → 结果全 0;
  • 全非零 → 数组保持不变。

五、复杂度分析与正确性说明

  • 时间复杂度

单次遍历数组 → O(n)

  • 空间复杂度

只用常数变量 → O(1)

  • 正确性保证(不变式):
  • [0..dest] 恒为非零区间,顺序正确;

  • 遍历结束时,剩余部分自然全是零。


六、常见坑总结

  • 为什么不用双指针对撞

因为零可能分散在数组中,对撞会打乱相对顺序

  • 自交换会不会影响效率?

不会,代价极小,也不影响正确性。

  • 能不能用 STL 一行解决?

可以用 stable_partition,但笔者更建议手写双指针法

  • 如果要移动指定值,而不是 0 ?

把条件 nums[cur] != 0 改成 nums[cur] != val 即可。


到这里,本文就结束啦。如果对读者有帮助,欢迎点赞、收藏和评论!
后续笔者会继续更新「双指针专题」系列,带你逐一攻克经典题目。

http://www.dtcms.com/a/431211.html

相关文章:

  • 图书馆网站建设教程android studio手机版
  • 网站建设合同报价花果园营销型网站建设
  • 最小二乘问题详解2:线性最小二乘求解
  • Multi-Arith数据集:数学推理评估的关键基准与挑战
  • 基于 Spring Security OAuth2 + JWT 实现 SSO
  • 数智经济时代医疗领域医学影像系统现状与趋势研究:多模态融合技术方向
  • 解读 2025 《高质量数据集 分类指南》
  • 为什么说这个是6dB de-emphasis”(即“6dB去加重”)--Con‘t
  • Eclipse 快捷键
  • 樟木头网站网络安全维护公司
  • 【EE初阶 - 网络原理】网络通信
  • 方案网站有哪些盗用别的公司网站模块
  • 做网站是否要去工商备案做网站群
  • Less resolver error:‘~antd/es/style/themes/index.less‘ wasn‘t found.
  • php网站验证码错误网站改版对用户的影响
  • vue中如何实现异步加载组件
  • 网站地图seo石城网站建设
  • 怎么防止网站被镜像wordpress seo 主题
  • 那些钓鱼网站是怎么做的页面设计上边距在哪里找
  • 中国移动idc建设网站wordpress 导航栏
  • @RequestBody与@PathVariable什么时候加
  • 2011 年真题配套词汇单词笔记(考研真相)
  • “AMQP协议深度解析:消息队列背后的通信魔法”之核心概念与SpringBoot落地实战
  • 网规答题点【summer解析】华为5G空口新技术有F-OFDM和SCMA,F-OFDM是基于OFDM的改进版本,可以 实现空口物理层分片,兼容LTE 4G。
  • 简约智能设备制造公司网站今天东营发生的重大新闻
  • Matrixport DAT与XBIT携DEX赋能生态,共赴新加坡TOKEN2049
  • 做网站需要什么营业执照中国建设企业协会网站首页
  • 微服务项目->在线oj系统(Java-Spring)--增删改(前端)
  • 软件网站开发评估免费拿货的代理商
  • C#基础05-控制语句