LeetCode--283. Move Zeroes

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]);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值