题目链接:移动零
题目描述:
给定一个数组
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进阶:你能尽量减少完成的操作次数吗?
解题思路:
-
用一个cur指针扫描整个数组,
dest指针
记录非零数序的最后一个位置, -
将
[0,dest]
全部元素都是保持相对顺序的非零元素,[dest+1,cur-1]
全部元素都是0
算法流程:
-
初始化
cur=0
(用来遍历数组),dest=-1
(指向非零元素序列的最后一个位置) -
cur依次往后遍历每个元素,遍历到的元素会有以下两种情况:
-
遇到的元素是0,
cur++
-
遇到的元素不是0,
dest++
,并且交换cur位置和dest
位置的元素,之后cur++
,扫描下一个元素-
因为
dest
指向的位置是非零元素区间的最后一个位置,如果扫描到一个新的非零元素,那么它的位置应该在dest+1
的位置上,因此dest
先自增1
-
dest++
之后,指向的元素就是0元素(因为非零元素区间末尾的后一个元素就是0),因次可以交换到cur所处的位置,实现[0,dest]
的元素全部都是非零元元素,[dest+1,cur-1]
的元素全是0
-
-
算法流程图:
c++版本代码
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int dest=-1;
for(int cur=0;cur<nums.size();cur++)
{
if(nums[cur])
{
swap(nums[++dest],nums[cur]);
}
}
}
};
C语言版本代码
void swap(int *n1,int *n2)
{
int temp=*n1;
*n1=*n2;
*n2=temp;
}
void moveZeroes(int* nums, int numsSize){
int cur=0;
int dest=-1;
while(cur<numsSize)
{
if(nums[cur])
{
dest++;
swap(&nums[dest],&nums[cur]);
}
cur++;
}
}