记录一下算法题的学习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元素都统计完了,剩下都是零,第二次遍历把末尾元素都赋值0for(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博客