目录
1.移动零
1.1题目描述
我们先来看题目描述,给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
1.2 题目解析
这道题的题目描述中,要求原地操作,那么我们可以使用双指针来操作这个题.
首先定义一个指针dest,和一个指针cur,让cur来遍历这个数组,如果遇到非0的,就和dest进行交换,直到cur遍历完这个数组即可.
第一步 定义两个指针 从左开始
第二步 cur往后走 遇到非0的元素就交换 交换以后dest在往右走.
直到全部遍历完即可.
1.3 代码编写
public void moveZeroes(int[] nums) {
int dest = 0;
for(int cur = 0 ; cur<nums.length; cur++){
if(nums[cur]!=0){
int tmp = nums[cur];
nums[cur] = nums[dest];
nums[dest] = tmp;
dest++;
}
}
}
2.复写零
2.1题目描述
本题为: 给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。
2.2题目解析
本题的意思很明显,就是遇到0了,写两遍,然后遇不到写一遍,直到把这个数组填充完即可.
如果不考虑那句就地修改就很简单,直接开辟另一个数组然后便利就能做完这道题,如果是竞赛不考虑复杂度的情况下,可以用这种暴力的解法来写,
我们按照题目要求,先考虑一下双指针能不能做到这道题,如果从前往后遍历的话, 如果遇到0了,那么后面的本来非0的元素也可能被覆盖掉,所以这种方法不可取
我们试试如果从后往前呢?
首先cur判断一下是不是0或者非0 如果非0 dest就复写一位 反之就两位,
我们发现从后往前貌似是可以的,
但是这里有一个问题,我们如何找到cur的位置呢?
我们可以通过双指针来先让dest走到数组的最后一个位置,然后就从后往前就行.
依旧是双指针,cur遇到非0,dest往后走一位,遇到0,dest往后走两位
走完大概是这个结果
注意 :如果最后是0,然后走两位越界了,就可能触发数组越界异常,所以我们得判断一下.
然后找到这两个位置以后,在使用从后往前的思路来走即可.
2.3代码编写
public void duplicateZeros(int[] arr) {
int cur = 0, dest = -1, n = arr.length;
while(cur<n){
if(arr[cur]!=0)
dest++;
else {
dest+=2;
}
if(dest>=n-1){
break;
}
cur++;
}
if(dest==n){
arr[n-1] = 0;
dest-=2;
cur--;
}
while(cur>=0){
if(arr[cur]!=0){
arr[dest--] = arr[cur];
}else{
arr[dest--] = 0;
arr[dest--] = 0;
}
cur--;
}
}