双指针:write 指针收集非零元素,剩余补零,保持非零相对顺序。
OJ: leetcodecn
题目 ID: move-zeroes
难度:入门
标签:双指针数组cpppython
日期: 2026-07-28 22:03
题意
将数组中的 0 全部移到末尾,同时保持非零元素的相对顺序。要求原地修改。
思路
维护一个 write 指针,指向下一个非零元素应该放置的位置。遍历数组,遇到非零元素就写入 write 位置并递增。遍历结束后,write 之后的位置全部置零。
也可以交换而非覆盖,写法更简洁但多一次赋值。
代码
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
*/
// main.cpp:双指针,write 指针收集非零元素,剩余补零。
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
void moveZeroes(vector<int> &nums) {
int w = 0;
for (int i = 0; i < (int)nums.size(); i++)
if (nums[i])
nums[w++] = nums[i];
while (w < (int)nums.size())
nums[w++] = 0;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n);
for (int &x : a)
cin >> x;
Solution().moveZeroes(a);
for (int x : a)
cout << x << ' ';
return 0;
}python
#!/usr/bin/env python3
from typing import List
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
w = 0
for i in range(len(nums)):
if nums[i]:
nums[w] = nums[i]
w += 1
for i in range(w, len(nums)):
nums[i] = 0
def main() -> None:
n = int(input())
nums = list(map(int, input().split()))
Solution().moveZeroes(nums)
print(*nums)
if __name__ == "__main__":
main()复杂度
- 时间复杂度:O(n),每个元素至多处理一次。
- 空间复杂度:O(1),只使用几个指针。
总结
"收集"型双指针适用于把满足某一条件的元素集中到数组前部,剩余位置用默认值填充。