实例
给定一个数组 int[] arr = {5,2,1,3} 删除数组中为 1 的元素,输出结果为 arr = {5,2,3}
解题思路
可以定义两个快慢指针,fastIndex、slowIndex。fastIndex 指针用来从原来 arr 数组中读取数据,slowIndex 指针用来指向读取出来的数据写入的位置,如下图示:
1、一开始两个指针都指向 arr 的起始位置 0
2、然后 fastIndex 往右移动,读取到当前指向的值,然后判断是否和要删除的元素相同,显然读取出来的 2 和 1(需删除的元素) 不相同
3、所以 slowIndex 也会跟着往右移动,并且还需要把从 fastIndex 位置读取出来的值填充到 slowIndex 指向的位置,如下图示:
4、接着 fastIndex 循环第 1 个步骤,继续往后移动,当 fastIndex 指向元素 1 的时候,发现就是要删除的元素,那么此时 slowIndex 指针不会往后移动,如下图示:
5、但是 fastIndex 会继续循环第 1 个步骤,继续往后移动,此时只想元素 3,判断和要删除的元素不相同 ,那么 slowIndex 就会往后移动了,并且还是会把 fastIndex 指向的值赋值给 slowIndex 指向的位置,注意此时的 falstIndex 指向的位置在元素 3 的位置,slowIndex 指向的是在元素 1 的位置,也就是讲 3 赋值给了 1,从而达到删除元素 1 的效果,如下图示:
6、注意此时新数组的长度就是 slowIndex 就是我们新数组的长度,此时就是 size = 3。
代码如下
package main.suanfa;
import java.util.Arrays;
public class ArrDemo {
/**
* 删除数组中元素为 1 的值,数组底层是连续存储的,所以删除一个元素需要往前移动所有元素
* 这里采用:快慢指针算法解题
*
* 思路:
* 1、快指针一直往后读取数组中的值,如果读取的值和要删除的元素不一样,慢指针也一直往后移动
* 2、当快指针读取出的值和要删除的目标一样,那么慢指针不用往后移动,但是快指针还是要继续往后读取
* 3、每次快指针读取的值都写到慢指针指向的坐标处
*/
public static void main(String[] args) {
int[] arr = new int[]{5,2,1,3};
int fastIndex = 0;
int slowIndex = 0;
int target = 1;
for (; fastIndex < arr.length; fastIndex++) {
if (arr[fastIndex] != target) {
arr[slowIndex++] = arr[fastIndex];
}
}
for (int i = 0; i < slowIndex; i++) {
System.out.println(arr[i]);
}
}
}
输出结果如下:
新数组长度 size = 3
5
2
3
Process finished with exit code 0