【发布时间】:2015-05-26 04:24:22
【问题描述】:
我正在尝试提出一种算法来解决以下问题。
给定一个 id 数组
var ids = [8098272281362432, 7824519999782912];
在一个项目数组中查找所有匹配项。
var people = [
{
"id": 8098272281362432,
"age": 59,
"name": "Douglas Hunter"
},
{
"id": 625873891885056,
"age": 1,
"name": "Lottie Owen"
},
{
"id": 7824519999782912,
"age": 100,
"name": "Maud Wise"
},
{
"id": 2561552265773056,
"age": 115,
"name": "Annie Bennett"
}
];
方法 1
我可以通过按id (O(n log n)) 对两个数组进行排序然后从上到下遍历这两个数组一次来解决这个问题 (O(n))
var alg1 = function(people, ids) {
var matches = [];
var sortedPeople = people.sort(function(a, b) {
return a.id - b.id
});
var sortedIds = ids.sort(function(a, b) {
return a - b
});
var curPersonIndex = 0;
sortedIds.forEach(function(id) {
while (sortedPeople[curPersonIndex].id !== id) {
curPersonIndex++;
}
matches.push(sortedPeople[curPersonIndex]);
});
return matches;
};
方法 2
我虽然可以使用O(n) 算法来改进这一点,方法是创建 id 到人员的映射,然后我可以为每个 id 查找人员。
var alg2 = function(people, ids) {
var matches = [];
peopleMap = {};
people.forEach(function(person) {
//Is this O(1) or O(log n)?
peopleMap[person.id] = person;
});
ids.forEach(function(id) {
matches.push(peopleMap[id]);
});
return matches;
};
但是,当我对此进行测试时,这两种算法的表现似乎都差不多。 #1 在 chrome 中更快,#2 在 Firefox 中稍快。
http://plnkr.co/edit/FidAdBqS98RKebxaIlva?p=preview
我感觉将字段插入对象是O(log n) 而不是O(1),正如我所预料的那样。不过,我已经阅读了一些相互矛盾的帖子,所以我不确定。我想这可能取决于浏览器。有什么方法可以在 JavaScript 中使用 O(n) 算法始终如一地解决这个问题?
【问题讨论】:
-
如果您有工作代码并希望对其进行改进,我想知道codereview.stackexchange.com 是否是您发帖的最佳地点。
-
花费额外的时间来构建
peopleMap可能会为大型数据集带来更多回报,或者如果您创建一次地图然后重复查找。此外,您似乎没有利用 #1 中的排序数组,所以我想知道您为什么还要费心对它们进行排序。 -
数组是经常更新还是只更新一次?
-
@VikramBhat 数组只更新一次
标签: javascript algorithm time-complexity