算法学习之移动零

Jackey C/C++ 1,868 次浏览 没有评论

题目要求:

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

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes

解题代码:

#include <iostream>
#include <vector>

using namespace std;

class Solution {
public:
    // 时间复杂度:O(n)
    // 空间复杂度:O(n)
    void moveZeroes(vector<int>& nums) {
        vector<int> nonZeroElements;
        // 提取非零的元素
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i])
                nonZeroElements.push_back(nums[i]);
        }

        // 将非零的元素按顺序赋值给原有的数组
        for (int i = 0; i < nonZeroElements.size(); i++)
            nums[i] = nonZeroElements[i];

        // 将其他元素的值修改为0
        for (int i = nonZeroElements.size(); i < nums.size(); i++)
            nums[i] = 0;
    }
};

int main() {
    int arr[] = {0, 1, 0, 3, 12};
    vector<int> vec(arr, arr + sizeof(arr)/ sizeof(int));

    Solution().moveZeroes(vec);

    for (int i = 0; i < vec.size(); i++)
        cout<<vec[i]<<" ";
    cout<<endl;

    return 0;
}

不使用中间变量的解法:

class Solution {
public:
    // 时间复杂度:O(n)
    // 空间复杂度:O(1)
    void moveZeroes(vector<int>& nums) {

        int k = 0; // nums中,[0....k)的元素为非0元素

        // 遍历到i个元素,保证[0....i]中所有非0元素都按照顺序排列在[0...k)中
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i])
                nums[k++] = nums[i];
        }

        // 将nums剩余的位置设置为0
        for (int i = k; i < nums.size(); i++) {
            nums[i] = 0;
        }
    }
};

一次循环解决问题:

class Solution {
public:
    // 时间复杂度:O(n)
    // 空间复杂度:O(1)
    void moveZeroes(vector<int>& nums) {

        int k = 0; // nums中,[0....k)的元素为非0元素

        // 遍历到i个元素,保证[0....i]中所有非0元素都按照顺序排列在[0...k)中
        // 同时,[k....i] 为0
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i]) {
                if (i != k)
                    swap(nums[k++], nums[i]); // nums[k]与nums[i]进行值的交换
                else
                    k++;
            }
        }
    }
};

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Go