双指针 — 移动零

目录

[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;
            }
        }
    }
}
相关推荐
奋发向前wcx3 分钟前
P2590 树的统计 题目解析
数据结构·算法·深度优先
Hui Baby37 分钟前
Spring Security
java·后端·spring
imbackneverdie1 小时前
AI4S不止于分子药物:以MedPeer为代表的科研基建打开产业新增量
大数据·人工智能·算法·aigc·科研·学术·ai 4s
IT笔记1 小时前
【Rust】Rust Match 模式匹配详解
java·开发语言·rust
我才是银古2 小时前
构建 Java GIS 工具库:从碎片化 API 到统一抽象的设计实践
java·gis·geotools·gdal·esri
TPBoreas2 小时前
配置信息防泄露方案:.env 环境隔离详解(dotenv-java)
java·开发语言
额鹅恶饿呃2 小时前
C语言中的数据结构和变量
c语言·数据结构·算法
敲代码的嘎仔2 小时前
实习日志day6--实习日志day6--title命名规范化&businessType纠正&补充缺失的@Log注解&报警与通信模块补充&产出阶段总结文档
java·开发语言·人工智能·git·python·实习·大二
编程(变成)小辣鸡3 小时前
Spring事务失效场景
java·后端·spring
运行时记录3 小时前
prompt-optimizer skill
算法