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.

 

思路:

用两次for循环,从数组0位置开始依次检查每个值,若为0,则依次与后一个数字两两交换,整个数组完成一遍后,检查数组第一个值是否为0,若是,则进行第二遍检查,直到第一个值不为0。这种算法通过了编译和测试用例的检验,但是超时了。

我的代码:

class Solution {
public:
    void moveZeroes(vector<int>& nums) 
    {
        do
        {
            for(int i=0;i<nums.size();i++)
            {
                if (nums[i]==0)
                {
                    for(int j=i+1, temp=0;j<nums.size();j++)
                    {
                        temp=nums[j];
                        nums[j]=nums[j-1];
                        nums[j-1]=temp;
                    }
                }
            }
        }while(nums[0]==0);
    }
};

 

参考代码:

class Solution {
public:
    /* 
     * Solution (Calinescu Valentin)
     * ==============================
     *
     * One solution would be to store the position of the next non-zero element of the array.
     * Every position of the array, starting with position 0, must store this next non-zero
     * element until we can no more do that, case in which we need to add the remaining zeros
     * that we skipped.
     * 
     * 
     * Time Complexity: O(N)
     * Space Complexity: O(1)
     * 
     */
    void moveZeroes(vector<int>& nums) {
        int i = 0, poz = 0;
        for(i = 0; i < nums.size() && poz < nums.size(); i++)
        {
                while(nums[poz] == 0)
                    poz++;
                if(poz < nums.size())
                    nums[i] = nums[poz];
                else
                    i--; // we need 0 on position i, but i is increasing one last time
                poz++;
        }
        for(; i < nums.size(); i++)
            nums[i] = 0;
    }



    /*
     * Another implemtation which is easy to understand (Hao Chen)
     * ===========================================================
     *
     * We have two pointers to travel the array, assume they named `p1` and `p2`.
     * 
     *   1) `p1` points the tail of current arrays without any ZEROs.
     *   2) `p2` points the head of the rest array which skips the ZEROs.
     * 
     * Then we can just simply move the item from `p2` to `p1`.
     *
     */
    void moveZeroes(vector<int>& nums) {
        int p1=0, p2=0;

        // Find the first ZERO, where is the tail of the array.
        // (Notes: we can simply remove this!)
        for (; nums[p1]!=0 && p1<nums.size(); p1++);
        
        // copy the item from p2 to p1, and skip the ZERO
        for (p2=p1; p2<nums.size(); p2++) {
            if ( nums[p2] == 0 ) continue;
            nums[p1++] = nums[p2]; 
        }    
        
        //set ZERO for rest items 
        while ( p1<nums.size() ) nums[p1++] = 0;
    }

};

总结:

参考代码中,两种方法的核心就是把非零的数字提到数组前面,后面的全部置0,代码逻辑比较考验人呢,一般不容易想到吧XD;

posted @ 2016-02-23 01:49  torrescx  阅读(243)  评论(0编辑  收藏  举报