重复数据删除算法的时间复杂度

时间:2017-07-06 09:39:28

标签: javascript time-complexity complexity-theory

这是一个从数组中删除重复项的函数。



function dedupe(arr) {
    var seen = {};
    arr.forEach((e,i)=>{
        if (seen[e]) {
            arr.splice(i, 1);
        }
        seen[e] = true;
    });
    return arr;
}

console.log(dedupe([1, 2, 1, 3, 4]));




我对此功能的时间复杂性感兴趣。

如果我们假设Array由真实数组支持,那么可以按如下方式分析时间复杂度吗?

  • 分配seen:O(1)
  • 枚举所有元素:O(n)
  • 删除副本:O(n)(因为需要逐项重新分配?)
  • 返回O(1)

这是一个O(n ^ 2)算法吗?

修改

已针对索引问题进行了更正。



function dedupe(arr) {
    var seen = {};
    for(let i = 0; i < arr.length; i++) {
        const e = arr[i];
        if (seen[e]) {            
            arr.splice(i, 1);
            i--; // we have modified the array and need to continue from the current index
        }
        seen[e] = true;
    }
    return arr;
}

console.log(dedupe([1, 2, 1, 3, 1, 4, 4, 7, 6, 7, 7, 7, 1, 5]));
&#13;
&#13;
&#13;

对于那些因上述表现而感到不安的人,我认为这是O(N)。

我想在原地进行重复删除。使用Set可以在主机环境中维护订单。

&#13;
&#13;
function dedupe(arr) {
    var seen = new Set();
    for(let i = 0; i < arr.length; i++) {
        seen.add(arr[i]);
    }
    arr.length = 0; // empty the array
    return arr.concat(...seen.keys());
}

console.log(dedupe([1, 2, 1, 3, 1, 4, 4, 7, 6, 7, 7, 7, 1, 5]));
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:1)

一种方法是使用Javascript Set。你可以这样做:

const removeDuplicates = array => (new Set(array)).values()

这将返回一个迭代器,而不是一个数组,但是这很容易修复。此外,大多数浏览器都支持的设置。这种复杂性应该是O(n)。

另一种更类似于你的方法(但可能与Set相同,因为我猜它是使用相同的底层结构实现的)将是这样的:

const removeDuplicates = array =>
    Object.keys(array.reduce((agg, x) => { agg[x] = true; return agg }, {}))

这个时间复杂度应该是O(m + n),其中m是唯一项的数量,它总是<= n,因此是O(n)。

此外,您制定的时间复杂度似乎也是正确的。

答案 1 :(得分:0)

您可以按索引过滤保存seen

var t1 = [1, 2, 1, 1, 3, 1, 1, 4];
function uniqueList(list) {
    return list.filter(function (value, index, arr) {
        return list.indexOf(value) == index;
    });
}
console.log(t1);
console.log(uniqueList(t1));

答案 2 :(得分:0)

我的回答是,构建一个新数组。也许是O(n)。

&#13;
&#13;
function dedupe(arr) {
    var result = [];
    var seen = {};
    for(let i = 0; i < arr.length; i++) {
        const e = arr[i];
        if (seen[e]) {            
            //skip
        } else {
            seen[e] = true;
            result.push(e);
        }
        
    }
    return result;
}

console.log(dedupe([1, 2, 1, 3, 1, 4, 4, 7, 6, 7, 7, 7, 1, 5]));
&#13;
&#13;
&#13;