记录一下算法题的学习2
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums =[0,1,0,3,12]
输出:[1,3,12,0,0]
示例 2:
输入: nums =[0]
输出:[0]
分析思考:
什么是双指针?
双指针即用两个不同速度或不同方向的指针对数组或对象进行访问,通过两个不同指针的碰撞从而达到特定的目的。
左右指针通常在数组有序的情况下,从最小和最大端同时对数组进行处理,对满足特定条件的数组元素进行成对处理,而快慢指针逐渐靠拢直至发生碰撞,则遍历完所有数组
我们在这里使用左右指针
初级代码展示
class Solution {
public void moveZeroes(int[] nums) {
int i=0;
int j=0;
//判断该数组是否为空或者只有一个值,就不需要排序
if(nums==null||nums.length<=1){
System.out.println("数组为空或数组只有一个值,不需要移动顺序");
}
//第一次遍历,j指针记录非0的个数,只要是非0的都赋给nums[j],这里nums[j++]实际上最开始就是nums[0],而不是nums[1];
for(i=0;i<nums.length;i++){
if(nums[i]!=0){
nums[j++]=nums[i];
}
}
//第二次遍历,由于非0元素都统计完了,剩下都是零,第二次遍历把末尾元素都赋值0
for(i=j;i<nums.length;++i){
nums[i]=0;
}
//第三次遍历,把得到的移动零的正确数组遍历出来
for(j=0;j<nums.length;j++){
System.out.println(nums[j] );
}
}
}
上一个代码,经过多次遍历,时间过慢,(太搞笑了!)
我们进阶代码展示
class Solution {
public void moveZeroes(int[] nums) {
int index=0,temp=0;
for(int i=0;i<nums.length;i++ ){
if(nums[i]!=0){
temp=nums[i];
nums[i]=nums[index];
nums[index]=temp;
index++;
}
}
return;
}
}
仔细分析:
右指针遍历出每一个 !=0 的数,与左指针(从下标 0 开始)交换,每交换一次就要左指针 ++
举例展示nums=[0,1,0,3,12]
nums值 | 0 | 1 | 0 | 3 | 12 |
索引 | 0 | 1 | 2 | 3 | 4 |
当遍历出第一个!=0的数时,与左指针(从下标 0 开始)交换,结果展示
nums值 | 1 | 0 | 0 | 3 | 12 |
索引 | 0 | 1 | 2 | 3 | 4 |
当遍历出第二个!=0的数时,与左指针下标 1 交换,结果展示
nums值 | 1 | 3 | 0 | 0 | 12 |
索引 | 0 | 1 | 2 | 3 | 4 |
当遍历出第三个!=0的数时,与左指针下标 2 交换,结果展示
nums值 | 1 | 3 | 12 | 0 | 0 |
索引 | 0 | 1 | 2 | 3 | 4 |
直至整个遍历完为止。
结语:
还可以查看
移动零算法_冰鲜柠檬汁的博客-CSDN博客