leetcode 283.移动零

leetcode 283.移动零

题目描述

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。

解题思路

采用尽可能少的操作次数。可以把当前的零值元素改成下一个非零值的元素,并且用一个变量记录有多少个非零值,然后以此变量作为下标,把后面的元素全部置为零,就可以完成零元素的后移。

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int nonZeroIndex = 0;
        for(int i=0; i<nums.size(); i++){
            // 把零元素用非零值代替
            if(nums[i] != 0){
                nums[nonZeroIndex] = nums[i]; 
                nonZeroIndex++;
            }
        }
        // 把nonZeroIndex以后的元素全部置为零。
        for(int i=nonZeroIndex; i<nums.size(); i++){
            nums[i] = 0;
        }
    }
};

同样的方法,还有一种优化的方法

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int index = 0;
        for(int i=0; i<nums.size(); i++){
            // 如果是非零元素,那么就是保持自身不变,如果是零,把零元素不断的和非零元素交换,
            if(nums[i] != 0){
                int temp = nums[index];
                nums[index] = nums[i];
                nums[i] = temp;
                index++;
            }
        }
    }
};

这是一种相对而言操作次数较多的写法,从数组的两端开始同时处理,首先确定右端非零元素的下标,再从左侧开始查找零元素,找到零元素就往后移。

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int left = 0;
        int right = nums.size()-1;
        // 寻找右侧非零元素的下标,同时右侧下标不等于零,若是零,表示所有的元素都是零。
        while(nums[right] == 0 && right > 0){
            right--;
        }
        // 从左侧开始查找非零元素
        while(left < right){
            // 如果非零,左侧下标加一
            if(nums[left] != 0){
                left++;
                continue;
            }
            // 如果是零元素,通过交换元素的方式,把零元素移到右侧。
            for(int i=left; i<right; i++){
                int temp = nums[i];
                nums[i] = nums[i+1];
                nums[i+1] = temp;
            }
            right--;
        }
    }
};

欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分享技术问题,我们一起学习进步
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值