1.复写0
https://leetcode.cn/problems/duplicate-zeros/
题目描述
给你一个长度固定的整数数组 arr
,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。
示例 1:
输入:arr = [1,0,2,3,0,4,5,0] 输出:[1,0,0,2,3,0,0,4] 解释:调用函数后,输入的数组将被修改为:[1,0,0,2,3,0,0,4]
思路
利用双指针算法
题目上说是就地进行修改,所以两个指针指向同一个数组
要么从前向后要么从后向前,因为是遇到将原数组中的0重复,并且后面的数向后平移,如果从前向后的话,会覆盖后面的数字,所以从后向前遍历,遇到非0写一次,遇到0写两次
步骤
1.cur负责遍历数组,dest负责在具体数组下标写数字
2.dest初始为数组的最后一个位置,cur的位置不能确定
3.需要找cur的位置,这时我们可以从前向后遍历
cur初始为0,dest初始为-1;
cur为0,dest加2,cur++;
cur不为0,dest加1,cur++;
等到dest到最后一个位置时,cur-- 的位置就是我们要的位置
但是有些时候,dest有可能会越界,比如下面这种情况
cur确实应该是从此位置开始,但dest已经越界,
此时需要特殊处理:当这种情况下,先让数组的 dest-1 下标置为0,然后dest--,cur--,相当于特殊处理了第一步,此时再正常往下进行就可以了
if (dest == arr.length){ arr[dest-1] = 0; dest-=2; cur--; }
4.此时cur的位置已经确定,接着就是循环赋值了
当cur>=0 时,判断arr[cur]是否等于0,如果等于0,arr[dest--] = 0 重复两次,cur--;
代码
public void duplicateZeros(int[] arr) {
int cur = 0;
int dest = -1;
while (dest<arr.length-1){
if (arr[cur]!=0){
dest++;
}else {
dest += 2;
}
cur++;
}
cur--;
if (dest == arr.length){
arr[dest-1] = 0;
dest-=2;
cur--;
}
while (cur>=0){
if (arr[cur]!=0){
arr[dest] = arr[cur];
dest--;
cur--;
}else {
arr[dest--] = 0;
arr[dest--] = 0;
cur--;
}
}
}