复写零
给你一个长度固定的整数数组 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]
示例 2:
输入:arr = [1,2,3]
输出:[1,2,3]
解释:调用函数后,输入的数组将被修改为:[1,2,3]
提示:
1 <= arr.length <= 104
0 <= arr[i] <= 9
1.题目解析
2.讲解算法原理
解法: 双指针算法,先根据“异地”操作,然后优化成双指针下的“就地”操作
(1)异地操作来实现
以示例1来画图阐述:
(2)双指针下的“就地”操作
从左到右,发现不行。
开始从右向左尝试,发现可以
总结思路
- 先找到最后一个“复写”的数;
- "从后向前”完成复写操作
待完成的问题:如何找到最后一个“复写”的数?
答:也是一个双指针算法。
dest
判断是否从前往后遍历完这个数组的时候,对cur
这个下标指向的数判断是否为0
。
cur
不为0,cur
++,dest
++;
cur
为0,cur
++,dest
。
用双指针书写代码运行的过程
- 先判断
cur
位置的值- 决定
dest
向后移动一步或者两步- 判断一下
dest
是否已经到结束位置cur
++
画图阐述找到最后一个“复写”的数的过程
存在的特殊情况
解决: 对边界情况进行处理一下
存在当
dest
在n的位置时,n-1的位置设为0,cur
- -,dest
-= 2
3.编写代码
class Solution {public void duplicateZeros(int[] arr) {int cur = 0, dest = -1, n = arr.length;// 1.先找到最后一个需要复写的数while (cur < n) {if (arr[cur] == 0) {dest += 2;} else {dest += 1;}if (dest >= n - 1) {break;}cur++;}// 2.处理一下边界情况if(dest==n){arr[n-1]=0;cur--;dest-=2;}//3.从后向前完成复写操作while(cur>=0){if(arr[cur]!=0){arr[dest--]=arr[cur--];}else{arr[dest--]=0;arr[dest--]=0;cur--;}}}
}
运行结果: