双指针 — 移动零

目录

[1. 题目解析](#1. 题目解析)

[2. 算法讲解](#2. 算法讲解)

[3. 编写代码](#3. 编写代码)


1. 题目解析

283. 移动零

移动0的题型是为数组划分,或者数组分块。

这类题的特点是给我们一个数组,再制定一个规则,让我们在这个规则下,把数组划分成不同的区间:

这个题的标准是:

在原数组的基础上,把所有非0元素划分到数组的左边,所有0元素分配到数组的右边 。

这样,所有数组元素就被划分成两个区间:

解决这个题目,我们用一种非常经典的算法,就是双指针算法(利用数组下标充当指针)


2. 算法讲解

双指针算法:我们定义两个指针 dest ,cur

这两个指针从左往右遍历数组的时候,会把整个数组划分为三个区间:

我们先不管这些区间,先来介绍这两个指针的作用:

cur :从左往右扫描数组,遍历数组

dest:已处理的区间内,非零元素的最后一个位置

这时候,cur会把整个数组划分成两个区间,**左边为已经处理的区间,右边为未处理的区间,**怎么处理的我们先不管;

dest指针起到分割线的作用,将cur左边已经处理过的区间又细分成两个小区间。

这里又有一个小问题:为什么第二个区间是到cur-1呢?

这又回到cur指针本身的含义上,cur这个指针用于从左往右扫描数组,而这三个区间分别代表不同的含义:

当cur走到n下标,就说明这个数组已经全部扫描完成。这时候,数组就被 dest 划分成两部分;也就是刚刚三个区间,只剩下前面两个区间,其中,左边部分是非0元素,右边部分是0元素。

那么接下来,我们要做的就是,让这两个指针从左往右扫码数组的过程中,保持两个指针划分的三个区间的性质。


以这个图的数组为例子:

cur刚开始初始化为这个数组的0下标位置;

对于 dest 指针,它表示非0元素的最后一个位置,刚开始扫描数组的时候,并没有非0元素;所以 刚开始让dest指向数组-1下标的位置。


刚开始dest先不动,因为cur是扫描数组的,所以先让cur先动。cur从前往后移动的过程中,会出现两种情况,遍历的元素是否为0:

当cur遇到0元素时,我们要保证 非0 0 未扫描 这三个区间的性质不变:

刚开始,cur指向0下标的数组元素,值为0 ;

在cur遇到0元素时,如cur当前遍历的0下标元素0。我们仅需要让cur向后移动一位即可。

cur向右移动一位,cur左边的区间[dest+1,cur-1]中,都是0元素。

所以cur在遍历到0元素,不做任何处理。


在cur遍历到非0元素时,我们让当前遍历的元素加入最左边的区间 [0 ,dest]

所以相当于 [0,dest] 这个区间中,多了一个元素,我们让dest往右移动一位:

移动好dest后,cur先不动,这时候交换cur和dest下标的元素

所以cur当前遍历的元素,在交换后,相当于已经被处理过了,cur向后移动一位:


综上所述,如果cur遍历的元素是0元素,则不做任何处理;

如果cur遍历到非0元素时,[0,dest]区间就要多一个元素,所以让dest指针往后移动一位,cur先不动;

让dest指向的元素与cur指向的元素进行交换,cur++;以 cur<n 为循环终止条件。


3. 编写代码

对于这个题目,对cur指针的所有调整,都通过for循环完成,不用再在if语句中调整cur

在cur遍历到0元素时,不做任何处理;所以,我们在for循环中,只要写cur遍历到非0元素的处理方法即可:

java 复制代码
class Solution {
    public void moveZeroes(int[] nums) {
        int dest = -1;

        for(int cur = 0;cur<nums.length;cur++){

            if(nums[cur]!=0){
                dest++;
                int tmp=nums[cur];
                nums[cur]=nums[dest];
                nums[dest]=tmp;
            }
        }
    }
}
相关推荐
纪元A梦12 分钟前
华为OD机试真题——绘图机器(2025A卷:100分)Java/python/JavaScript/C++/C/GO最佳实现
java·javascript·c++·python·华为od·go·华为od机试题
24k小善26 分钟前
FlinkSql入门与实践
java·大数据·flink·云计算
CodeCraft Studio39 分钟前
Excel处理控件Spire.XLS系列教程:Java设置Excel活动工作表或活动单元格
java·python·excel
Felven42 分钟前
A. Everybody Likes Good Arrays!
数据结构·算法
瓯雅爱分享1 小时前
任务管理系统,Java+Vue,含源码与文档,科学规划任务节点,全程督办保障项目落地提效
java·mysql·vue·软件工程·源代码管理
chxii1 小时前
2.3java运算符
java
余辉zmh1 小时前
【Linux系统篇】:信号的生命周期---从触发到保存与捕捉的底层逻辑
android·java·linux
小布不吃竹1 小时前
Maven的概念与初识Maven
java·maven
中东大鹅1 小时前
Maven进阶
java·maven
AI_RSER2 小时前
基于 Google Earth Engine 的南京江宁区土地利用分类(K-Means 聚类)
算法·机器学习·分类·kmeans·聚类·遥感·gee