题目描述:
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
- 必须在原数组上操作,不能拷贝额外的数组。
- 尽量减少操作次数。
算法:
我的思路是将0在从前往后移动的过程中将0聚集在一起,每一次都移动很多个0.
1. 找到第一个0所在的位置i处
2. 从i的位置+0子数组的长度j处开始移动,取t=j,直到t等于0为止或者移动的步数不超过原本0子数组的长度,在移动过程中更新0子数组中的值
3. 更新i的值,继续循环
我的思路很复杂,把简单的问题复杂化了。。。还是要多刷题
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 6 class Solution { 7 public: 8 //nums[i]和nums[j]代表[i,j)之间的值全为0 9 void moveZeroes(vector<int>& nums) { 10 // 注释这是我想了半小时左右的算法,虽然时间还不错,但是看到其他人的解题方式,实在是汗颜 11 // int size = nums.size(), i, j, t; 12 // for(i = 0; i < size && nums[i] != 0; i++); 13 // int zeroCnt = 1; 14 // while(t < size) 15 // { 16 // for(j = i + zeroCnt; nums[j] == 0; j++); 17 // zeroCnt = j - i; 18 // for(t = j; t - j < zeroCnt && nums[t] != 0 && t < size; t++) 19 // { 20 // nums[i + t - j] = nums[t]; 21 // nums[t] = 0; 22 // } 23 // i = i + t - j; 24 // } 25 int low = 0; 26 for(int i = 0; i < nums.size(); ++i){ 27 if(nums[i] != 0) //总是将非0值与0子数组的第一个互换,非常巧妙的双指针 28 swap(nums[low++], nums[i]); 29 } 30 } 31 }; 32 33 int main() 34 { 35 vector<int> vec = {0,1,0,3,12}; 36 Solution s; 37 s.moveZeroes(vec); 38 for(auto i : vec) 39 cout << i << ' '; 40 return 0; 41 }