为什么我利用辅助数组和没有用辅助数组的空间复杂度相似?

来源:3-4 即使简单的问题,也有很多优化的思路

骡子不会飞

2021-04-25

var moveZeroes = function(nums) {
    if(!(nums instanceof Array)) return nums;
    if(nums.length <= 1) return nums;
    let i = 0; // i作为[0, nums.length)的指针
    let k = 0; // [0, k)区间中,均为非0元素,k作为辅助指针
    while(i < nums.length) {
        if(nums[i] !== 0) {
            nums[k++] = nums[i];
        }
        i++;
    }
    // [k, nums.length)区间的全为0
    while(k < nums.length) {
        nums[k++] = 0; 
    }
};

为什么我在leetcode submit这个算法的结果,是和利用了辅助数组:

var moveZeroes = function(nums) {
    if(!(nums instanceof Array)) return nums;
    if(nums.length <= 1) return nums;
    // [0...nums.length)区间,
    // 遍历所有非0元素加入nonZeroArr,
    // 然后将nonZeroArr填入nums数组,
    // 剩下的nums元素都用0覆盖。
    const nonZeroArr = []
    for(let i = 0, len = nums.length; i < len; i++) {
        if(nums[i]) nonZeroArr.push(nums[i]);
    }
    for(let i = 0, len = nonZeroArr.length; i < len; i++) {
        nums[i] = nonZeroArr[i];
    }
    for(let i = nonZeroArr.length; i < nums.length; i++) {
        nums[i] = 0;
    }
};

这个算法的空间消耗是差不多的?
前者是:Memory Usage: 40.2 MB
后者是:Memory Usage: 40.7 MB
感觉不到前者空间复杂度是O(1)啊

写回答

1回答

liuyubobobo

2021-04-25

lc 的测试结果上,在系统上的基础内存消耗淹没了算法内部的内存消耗,尤其对于 O(n) 的内存来说。


你可以简单计算一下,这个问题的数据规模 n = 10^4。存储的是整型。一个整数是 32 bit = 4B。10^4 占的内存就是 4 *10^4 B 大约是 40 KB 即 0.04 MB。所以这部分空间的消耗其实很低。

(我的这个分析是基于 C/C++/Java 的分析,JS/Python 一类的语言一个 int 占的空间更大。)


这也是为什么在大多数算法设计中,内存不值钱的原因。除非特别极端的情况,否则通常情况下瓶颈都是性能而非内存。


继续加油!:)

1
0

玩转算法面试-- Leetcode真题分门别类讲解

课程配套大量BAT面试真题,高频算法题解析,强化训练

7408 学习 · 1150 问题

查看课程