减少比较两个数组的时间。时间复杂度

时间:2019-07-07 15:14:52

标签: javascript arrays ecmascript-6 time-complexity quadratic-programming

关于如何更好地解决此问题,我需要一些专家帮助/建议。我有两个数组,我需要比较这两个数组。 说我有2个要比较的数组,array1和array2,我需要检查数组1中的值是否存在于数组2中,在PHP中,我可以使用每次都可以使用的“ array_diff”函数,但是我不想使用array_diff,因为面试官说这不太容易,他希望我用另一种方式做。

默认情况下,我想到的是遍历array1,对于array1的每个值,再次比较array2,两次迭代,这将是(n * n)时间复杂度,请参见下面的代码。

我如何改善此算法/代码。我的目标是检查某个值是否在另一个数组中。我该如何改进这段代码,以免花太多时间比较两个数组。

这适用于面试问题以及我每天做的应用程序的日常编码。

const array1 = ["j1", "ff2", "3hj", "4sss", "5gh", "6ss", "7aqw"];
const array2 = ["klp3", "jks32", "44sss", "3hj", "5gh", "6ss", "7aqw"];

for (let index1 of array1){
  for (let index2 of array2){
    if (index1 === index2){
      console.log("Exists.", "index 1 value: " + index1, "Index 2 value: " + index2)
    }
  } 
}

我需要改善时间。另一个时间复杂度不是二次方。

6 个答案:

答案 0 :(得分:3)

您可以使用Set并检查另一个数组的每个项目。

var array1 = ["j1", "ff2", "3hj", "4sss", "5gh", "6ss", "7aqw"],
    array2 = ["klp3", "jks32", "44sss", "3hj", "5gh", "6ss", "7aqw"],
    set1 = new Set(array1);

array2.forEach(v => {
    if (set1.has(v)) console.log(v);
});

如果您不希望仅获得常见项目,则可以过滤数组。

var array1 = ["j1", "ff2", "3hj", "4sss", "5gh", "6ss", "7aqw"],
    array2 = ["klp3", "jks32", "44sss", "3hj", "5gh", "6ss", "7aqw"],
    common = array2.filter(Set.prototype.has, new Set(array1));

console.log(...common);

答案 1 :(得分:2)

我将其从数组更改为Map,然后搜索

const array1 = ["j1", "ff2", "3hj", "4sss", "5gh", "6ss", "7aqw"];
const array2 = ["klp3", "jks32", "44sss", "3hj", "5gh", "6ss", "7aqw"];

let arr1Map = new Map([...array1.map((v,i)=>[v,i])])

array2.forEach(val=> arr1Map.has(val) && console.log(val))

答案 2 :(得分:0)

这很慢

https://jsperf.com/array-indexof-vs-set-has

const array1 = ["j1", "ff2", "3hj", "4sss", "5gh", "6ss", "7aqw"];
const array2 = ["klp3", "jks32", "44sss", "3hj", "5gh", "6ss", "7aqw"];
console.log(
  array1.filter((arr1) => array2.indexOf(arr1) != -1)
);

答案 3 :(得分:0)

您可以使用include和indexOf:

$

答案 4 :(得分:0)

您可以使用哈希表存储第一个数组元素,然后查询第二个数组元素。在O(n)中可以这样工作:

  1. 在HashSet中设置元素将采用O(n)。

  2. 根据摊销分析,查询HashSet中的元素将为O(1)。

答案 5 :(得分:0)

将每个值添加到array1时,也将其添加到对象/缓存:

var cache = {};
...
...
for (index in array2) {
    cahce.array1_value = array1_value + '##' + array2[index] + '%%' + index;
}

然后,当您检查时,请执行以下操作:

 for (let index1 of array1){
    var s = split(cache[array[index1]], '%%');
    if (cache[array1[index1]] === s[0]){
      console.log("Exists." + index1 + '/' + s[1]);
    }
  }

这是未经测试的,仅供参考。

应该具有O(n)的复杂度。

这还取决于您首先填充哪个数组

但是当同时创建两个数组(您没有提到如何创建数组)时,它将不起作用。

创建数组会花费额外的时间,但是没有人告诉我们应该考虑到它。 :) 另外,此解决方案适用于实际应用,但可能不适用于面试。