LeetCode--283. Move Zeroes

来源:互联网 发布:软件绿灯测试概念 编辑:程序博客网 时间:2024/05/09 14:19

283. Move Zeroes

题目描述:

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:

  1. You must do this in-place without making a copy of the array.
  2. Minimize the total number of operations.
大致的意思就是给一个数组,将数组中所有的0移到数组的末尾,并且保证非零数字的顺序不能变。


代码如下:

class Solution {public:    void moveZeroes(vector<int>& nums) {        vector<int>::iterator it=nums.begin();        for(int i=0;i<nums.size();i++){    //遍历数组一遍            if(*it==0){                it=nums.erase(it); //如果为0,将其删除,此时it指向被删除的0的下一个元素                nums.push_back(0); //向数组的末尾放一个0            }            else{      //不是0,比较下一个数值                it++;            }        }    }};

提交后,用时22ms,击败了22.22%的C++程序。


LeetCode提供的最佳解法如下:

Approach #3 (Optimal) [Accepted]

The total number of operations of the previous approach is sub-optimal. For example, the array which has all (except last) leading zeroes: [0, 0, 0, ..., 0, 1].How many write operations to the array? For the previous approach, it writes 0's n-1n1 times, which is not necessary. We could have instead written just once. How? ..... By only fixing the non-0 element,i.e., 1.

The optimal approach is again a subtle extension of above solution. A simple realization is if the current element is non-0, its' correct position can at best be it's current position or a position earlier. If it's the latter one, the current position will be eventually occupied by a non-0 ,or a 0, which lies at a index greater than 'cur' index. We fill the current position by 0 right away,so that unlike the previous solution, we don't need to come back here in next iteration.

In other words, the code will maintain the following invariant:

  1. All elements before the slow pointer (lastNonZeroFoundAt) are non-zeroes.

  2. All elements between the current and slow pointer are zeroes.

Therefore, when we encounter a non-zero element, we need to swap elements pointed by current and slow pointer, then advance both pointers. If it's zero element, we just advance current pointer.

With this invariant in-place, it's easy to see that the algorithm will work.

 首先设置一个变量lastNonZeroFoundAt,初值为0,用来记录“最后一个非零数字的下标”,最后是相对来讲的,设置变量cur=0用来遍历数组,cur的值就是当前遍历到的位置。如果nums[cur]为非零元素,则交换nums[lastNonZeroFoundAt]和nums[cur]的值并且lastNonZeroFoundAt++,cur++,如果nums[cur]为零,则只需cur++,写一个数组模拟一下会更容易理解,官方代码如下:

void moveZeroes(vector<int>& nums) {    for (int lastNonZeroFoundAt = 0, cur = 0; cur < nums.size(); cur++) {        if (nums[cur] != 0) {            swap(nums[lastNonZeroFoundAt++], nums[cur]);        }    }}

0 0
原创粉丝点击