双指针 — 移动零

目录

[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;
            }
        }
    }
}
相关推荐
丫头,冲鸭!!!几秒前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法
Re.不晚4 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
雷神乐乐10 分钟前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven
码农派大星。14 分钟前
Spring Boot 配置文件
java·spring boot·后端
顾北川_野21 分钟前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
江深竹静,一苇以航23 分钟前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
confiself39 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
Wlq041544 分钟前
J2EE平台
java·java-ee
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
为什么这亚子1 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算