给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶:你能尽量减少完成的操作次数吗?
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/move-zeroes
想法1:双指针(我自己的想法,但是没有写出来,只能抄袭官方的)
我觉得自己没有想清楚的点在于
1.双指针到底指向的是什么?
class Solution {
//双指针思路
//双指针思路的重点是找到指针到底指的是什么?以及怎么将指针挪动。
//指针x 是已处理好的尾部,y是待处理的数字的头部
//这里简单解释下什么叫做处理?
//处理的逻辑是指:将非0数字往前移动
public void moveZeroes(int[] nums) {
int n = nums.length ,x = 0 ,y = 0;
//循环结束条件:没有待处理数字即可
while(y < n){
//如果发现待处理的数字为不等于0
if(nums[y] != 0){
//交换已处理好的尾部的和待处理数字的头部的值。
swap(nums,x,y);
//交换完之后,就把已处理的尾部数字+1
x++;
}
//待处理数字头部+1
y++;
}
}
private void swap(int[] nums,int start,int end){
int temp = nums[start];
nums[start] = nums[end] ;
nums[end] = temp;
}
}
想法2:循环一次
class Solution {
//思路,设置坐标,x标记非0的结束位置
public void moveZeroes(int[] nums) {
int x = 0;
for(int i = 0; i < nums.length ; i++){
if(nums[i] != 0){
swap(nums,i,x);
x++;
}
}
}
private void swap(int[] nums,int start,int end){
int temp = nums[start];
nums[start] = nums[end] ;
nums[end] = temp;
}
}
其实不难发现,两者基本一致。