leetCode #283 move zeroes
大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang
解法一
-> 从nums[0]开始,依次扫描0的个数count,每个元素都应该向前移动count个位置,最后再将最后count个元素赋值为0
实现如下:
1 class Solution { 2 public: 3 void moveZeroes(vector<int>& nums) { 4 int count = 0; 5 for (int i = 0; i < nums.size(); ++i) 6 { 7 if (nums[i] != 0) 8 { 9 nums[i - count] = nums[i]; 10 } 11 else 12 { 13 ++count; 14 } 15 } 16 while (count) 17 { 18 nums[nums.size() - count] = 0; 19 --count; 20 } 21 } 22 };
解法二
-> 扫描一遍nums中的元素,用p来表示可以放置非零元素的索引。只有当扫描的元素非零时,我们需要将这个元素放置到p的位置,并将p的位置再向后挪。
或这样理解:
-> 将nums中非零元素全部放置在[0,p) 这个区间,剩余的部分赋值为0
代码如下
1 class Solution { 2 public: 3 void moveZeroes(vector<int>& nums) { 4 int p = 0; 5 for (int i = 0; i < nums.size(); ++i) 6 { 7 if (nums[i]) 8 { 9 nums[p++] = nums[i]; 10 } 11 } 12 for (int j = p; j < nums.size(); ++j) 13 { 14 nums[j] = 0; 15 } 16 } 17 };
细心的你可能已经发现了,解法一和解法二本质是一样的,只是一个记录的是跨度count,一个记录的是下标p。
解法三
我们对上面的步骤进行优化,也就是把赋值(=)换成交换(swap()),这样就无需再对后面的0元素赋值了。
代码如下:
1 class Solution { 2 public: 3 void moveZeroes(vector<int>& nums) { 4 int p = 0; 5 for (int i = 0; i < nums.size(); ++i) 6 { 7 if (nums[i]) 8 { 9 swap(nums[p++], nums[i]); 10 } 11 } 12 } 13 };
优化解法三
考虑没有0元素的情况,那么原始的解法三会出现元素与自己交换的情况,对此,我们对两种情况进行处理,即,若i==p和i!=p这两种情况,前者并不需要做swap。
改进后的代码如下:
1 class Solution { 2 public: 3 void moveZeroes(vector<int>& nums) { 4 int p = 0; 5 for (int i = 0; i < nums.size(); ++i) 6 { 7 if (nums[i]) 8 { 9 if (i != p) 10 { 11 swap(nums[p++], nums[i]); 12 } 13 else 14 { 15 ++p; 16 } 17 } 18 } 19 } 20 };
限于小鸭酱水平有限,错误的地方或有更好的办法请指出,非常感谢!