题目
思路
双指针:要让0后移,相当于非0向前移动; 如果for从前往后遍历,先遍历到前面的位置,则可以把非0元素覆盖在此位置
- i:代表待覆盖位置,即0的位置
- j:遍历去寻找非0
void moveZeroes(vector<int>& a)
{
int n = a.size();
int i = 0;
while(i<n && a[i]!=0) //i负责寻找0的位置,即待覆盖位置
{
i++;
}
//此时i位于0上
int j = i+1;
while(j<n) //j负责找非0,找到则覆盖i
{
if(a[j] != 0)
{
std::swap(a[i],a[j]);//std标准库函数
i++;
}
j++;
}
}
总结
官方题解一次for遍历很巧妙,i,j初始位置均设为0,相同位置。
例如 8 9 0 6 1 5
while (j < n)
{
if (a[j] != 0)
{
swap(a[i], a[j]);
i++;
}
j++;
}
初次相同位置,则只要a[j] != 0,则交换,同自己交换,则i的位置也可更新。
- 只要位置上是
非0,则i、j永远处于相同位置 - 而只要遇到
0,则i会停止,该位置就是的,等待被覆盖的位置