Given an array nums
, write a function to move all 0
's to the end of it while maintaining the relative order of the non-zero elements.
For example, given nums = [0, 1, 0, 3, 12]
, after calling your function, nums
should be [1, 3, 12, 0, 0]
.
Note:
- You must do this in-place without making a copy of the array.
- Minimize the total number of operations
题目要求保持非零数字相对位置不变的前提下,把0移到末尾
最开始的思路是遇见0之后,把所有的数字都向前移动一位,通过了大部分测试用例,但是无法处理连零的问题,代码如下:
1 class Solution {
2 public:
3 void moveZeroes(vector<int>& nums) {
4 int size = nums.size();
5 for(int i=0;i<size;i++)
6 {
7 if(nums[i]==0)
8 {
9 for(int j=i+1;j<size;j++)
10 nums[j-1]=nums[j];
11 nums[size-1]=0;
12 }
13 }
14
15 }
16 };
换个思路,遍历两遍向量,记录下来0的数量,将非零数字存入新的向量,最后再将0补进新的向量,时间空间复杂度均是O(n),代码如下:
1 void moveZeroes(vector<int>& nums) {
2 int n = nums.size();
3
4 // Count the zeroes
5 int numZeroes = 0;
6 for (int i = 0; i < n; i++) {
7 numZeroes += (nums[i] == 0);
8 }
9
10 // Make all the non-zero elements retain their original order.
11 vector<int> ans;
12 for (int i = 0; i < n; i++) {
13 if (nums[i] != 0) {
14 ans.push_back(nums[i]);
15 }
16 }
17
18 // Move all zeroes to the end
19 while (numZeroes--) {
20 ans.push_back(0);
21 }
22
23 // Combine the result
24 for (int i = 0; i < n; i++) {
25 nums[i] = ans[i];
26 }
27 }
进一步优化,用两个指针,第一个指针记录最后一个非零元素应该在的位置,第二个指针负责遍历,遇见非零元素就把发赋值给第一个元素所在位置,然后第一个指针前进一个,第二次遍历则是把第一个指针到向量的末尾全部赋值为0。时间复杂度O(n),空间复杂度O(1);
1 void moveZeroes(vector<int>& nums) {
2 int lastNonZeroFoundAt = 0;
3 // If the current element is not 0, then we need to
4 // append it just in front of last non 0 element we found.
5 for (int i = 0; i < nums.size(); i++) {
6 if (nums[i] != 0) {
7 nums[lastNonZeroFoundAt++] = nums[i];
8 }
9 }
10 // After we have finished processing new elements,
11 // all the non-zero elements are already at beginning of array.
12 // We just need to fill remaining array with 0's.
13 for (int i = lastNonZeroFoundAt; i < nums.size(); i++) {
14 nums[i] = 0;
15 }
16 }
再优化操作方面,只遍历一遍,两个指针,思路同上,这次赋值变成交换位置,交换的次数为非零元素的个数
1 void moveZeroes(vector<int>& nums) {
2 for (int lastNonZeroFoundAt = 0, cur = 0; cur < nums.size(); cur++) {
3 if (nums[cur] != 0) {
4 swap(nums[lastNonZeroFoundAt++], nums[cur]);
5 }
6 }
7 }