题目描述
题干:
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
题解思路
把0都移动到数组最后但是不改变其他数字顺序,遍历的话就太麻烦了,因为不改变相对顺序,就能想到双指针的思路
官方题解给的双指针解释真的是晦涩难懂,虽然思路我是知道的,但是他的表述不太好,他的解释是这样的
使用双指针,左指针指向当前已经处理好的序列的尾部,右指针指向待处理序列的头部。
右指针不断向右移动,每次右指针指向非零数,则将左右指针对应的数交换,同时左指针右移。
因为他没有说什么是处理好的序列,其实翻译过来就是,左右两个指针,右指针遇到非零就和左指针进行转换
这样最后两个指针最后中间都是0,左指针左边的元素全都交换为非零数字
这里交换用的swap方法,我自己一开始没想写多余的方法,直接在原来的基础上交换赋值,但是这样会发现有特殊情况
如果遇到像 [1] 这种就会覆盖掉以前的值,变成 [0] ,所以最好是选择自己写swap方法
正确代码
class Solution {
public void moveZeroes(int[] nums){
int left = 0,right = 0;
while (right < nums.length){
if (nums[right] != 0){
swap(nums,left,right);
left++;
}
right++;
}
}
public void swap(int[] nums,int a,int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}
总结
双指针的思想有点在于不用多次遍历,而且不需要使用额外空间,而且在使用的时候可以一般都是定义left和right两个指针
但是有时候我记得因为特殊情况,也可以用for中i代替自己定义新的指针来简化代码,这里的指针当然只是自己心里定位的指针,并不是C中的指针
因为Java是一种值传递的语言,不存在指针,而且不需要C那样自己处理空间,并且也没有麻烦的垃圾回收机制,虚拟机可以自动释放过期对象
如果文章存在问题或者有更优秀的题解,欢迎在评论区斧正和评论,各自努力,你我最高处见