题目描述
给你一个长度固定的整数数组 arr,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
注意:请不要在超过该数组长度的位置写入元素。
要求:请对输入的数组就地进行上述修改,不要从函数返回任何东西。
示例
示例 1:
输入:[1,0,2,3,0,4,5,0]
输出:null
解释:调用函数后,输入的数组将被修改为:[1,0,0,2,3,0,0,4]
示例 2:
输入:[1,2,3]
输出:null
解释:调用函数后,输入的数组将被修改为:[1,2,3]
解题过程
思路及步骤
(1)借助虚拟数组来完成,虚拟数组的大小元原数组 arr 相同,变量 j 用来记录虚拟数组中的数组元素个数;
(2)使用指针 i 去遍历原数组 arr,如果 arr[i] != 0,则 i 和 j 同时自增 1,如果 arr[i] == 0,则此时便需要进行复写 0 的操作,所以 j 自增 2,i 自增 1,当 j >= arr.length 时停止遍历;
(3)此时 i 即为对原数组进行复写 0 操作之后会出现在虚拟数组中的最后一个元素的下标(注意理解);
(4)因为 j 表示虚拟数组中的元素个数,并不是下标,所以还需要对 j 进行自减 1 操作,需要特殊情况:当原数组 arr 的最后一个元素为 0 并且复写 0 之后 j > arr.length 了,则此时需要对 j 自减 2,同时给 arr[j] 赋值为 0,之后再进行一次 j 自减 1,i 自减 1 操作;
(5)之后从右到左进行复写 0 操作,如果 arr[i] == 0,则 arr[j] 和 arr[j - 1] 都赋值为 0,并进行 j 自减,2,i 自减 1 操作;如果 arr[i] != 0,则将当前 arr[i] 的值赋值给 arr[j],同时进行 i 和 j 的自减 1 即可
代码展示
public class DuplicateZeros {
public void duplicateZeros(int[] arr) {
// 虚拟数组, 找出会出现在虚拟数组中的最后一个元素, 即 i
int i = 0;
int j = 0;
for (; i < arr.length; i++) {
if (arr[i] == 0) {
j += 2;
} else {
j++;
}
if (j >= arr.length) {
break;
}
}
// 处理原数组中最后一个元素等于 0 且复写之后越界的特殊情况
if (j > arr.length) {
if (arr[i] == 0) {
j = j - 2;
arr[j] = 0;
j--;
i--;
}
} else {
j--;
}
//System.out.println("i = " + i + ", j = " + j);
// 从右到左, 进行复写操作
while (j >= 0) {
arr[j] = arr[i];
if (arr[i] == 0) {
arr[j - 1] = arr[i];
j--;
}
i--;
j--;
}
}
public static void main(String[] args) {
int[] arr = {1,0,2,3,0,4,5,0};
new DuplicateZeros().duplicateZeros(arr);
}
}
1159

被折叠的 条评论
为什么被折叠?



