减少对象
的列表之间的比较复杂度O^2我有对象的两个列表:减少对象
list1 = [{value: 'X'}, {value: 'Y'}, ..., {value: 'Z'}];
list2 = [{value: 'A'}, {value: 'B'}, ..., {value: 'C'}];
我有这样的代码,检查在list2
值是否在list1
。如果是代码没有做任何事情,如果没有,它应该添加到list1
(这将创建一个新列表,list3
)。这意味着我正在做两个列表之间的联合,而不保留重复的值。
for (let i = list2.length-1; i >= 0; i--) {
let item = list2[i];
let shared = false;
for (let j = list1.length-1; j >=0; j--) {
let childItem = list1[j];
if (item.value === childItem.value) {
shared = true;
break;
}
}
if (!shared) { newValues.push(item); }
}
list3 = list1.concat(newValues);
这工作正常,但我想知道如果我可以改善这个O(n * m)。
我不确定列表是否总是按默认排序,但从我所看到的(列表1和列表2)总是按值排序。
实施例:
var list1 = [{value: 'bar'}, {value: 'baz'}, {value: 'foo'}, {value: 'foz'}];
var list2 = [{value: 'bar'}, {value: 'foo'}, {value: 'test'}, {value: 'testz'}];
var list3 = union(list1, list2);
list3 = [{value: 'bar'}, {value: 'baz'}, {value: 'foo'}, {value: 'foz'}, {value: 'test'}, {value: 'testz'}];
创建一组的list1
的值,并且它concating到list1
之前过滤由所述组中的值list2
:
var list1 = [{value: 'bar'}, {value: 'baz'}, {value: 'foo'}, {value: 'foz'}];
var list2 = [{value: 'bar'}, {value: 'foo'}, {value: 'test'}, {value: 'testz'}];
const union = (list1, list2) => list1.concat(
list2.filter(function({ value }) { // filter list2
return !this.has(value); // filter out items which value is in the set
}, new Set(list1.map(({ value }) => value))) // the set of list1 values
);
const list3 = union(list1, list2);
console.log(list3);
问题是关于改进(最坏的情况下)的复杂性。你的解决方案在这方面做得如何,它在渐近行为方面实际上更好吗? –
那么与我发布的代码相比,你的代码有哪些改进?是否因为你没有创建临时列表? – mk2
这是因为我没有循环内循环,它给你O(n * m)。 创建一个集合是O(2n)。过滤'list2'是O(m)。并列是O(n + m)。所以总的复杂度是O(3n + 2m),我们可以去掉O(n + m)的常量。 –
您可以使用单个循环并将该值存储在一个集合中供以后检查。复杂性:O(n)。
var list1 = [{ value: 'X' }, { value: 'Y' }, { value: 'C' }, { value: 'Z' }],
list2 = [{ value: 'A' }, { value: 'B' }, { value: 'C' }, { value: 'D' }],
list3 = list1
.concat(list2)
.filter((s => ({ value }) => !s.has(value) && s.add(value))(new Set));
console.log(list3);
.as-console-wrapper { max-height: 100% !important; top: 0; }
其实O(n + m)因为迭代list1 + list2 –
@OriDrori,对于线性复杂度,O(n)足以描述它。 –
当你说“在列表2的值是否在列表1”你的意思是,如果有的话,或者如果所有,价值观? –
我会添加一个例子来澄清 – mk2