【发布时间】:2015-08-17 20:52:43
【问题描述】:
您有 2 个数组。
arrA 为空。
arrB 充满了东西(它充满了什么并不重要,但假设它很大)。
当用户做某事时,会从 arrB 中删除一个项目,并将该项目放在 arrA 中。
当用户做不同的事情时,它会从 arrA 中提取项目并将其放入 arrB。
是否可以在循环中不包含循环的情况下执行此操作?
或者用计算机科学术语来说:
是否可以使用线性 ( ϴ(n) ) 时间/空间复杂度来做到这一点?
现在我有一些至少是 ϴ(n*k)
(其中n是arrB的长度,k是传递给applyItems的项目数):
var arrA = [], arrB = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
function addToArray(arrayToAddTo, item){
if(arrayToAddTo.indexOf(item) === -1){
arrayToAddTo.push(item);
}
}
function removeFromArray(arrayToRemoveFrom, item){
var i = arrayToRemoveFrom.length;
var temp = [];
while(i--){
if(arrayToRemoveFrom[i] !== item){
temp.push(arrayToRemoveFrom[i]);
}
}
return temp;
}
function applyItems(arrayOfItems){
var i = arrayOfItems.length;
while(i--){
var current = arrayOfItems[i]
addToArray(arrA, current);
arrB = removeFromArray(arrB, current);
}
}
applyItems([0, 5, 3]);
console.log(arrA);
console.log(arrB);
applyItems 有效,但效率不高。
这里是否可以降低时间/空间复杂度?
【问题讨论】:
-
您可以使用比手动循环更快的本地工具。
removeFromArray可以使用indexOf获取要移除的位置,然后使用splice将其移除。您也可以使用参考而不是每次都重新创建数组。 -
类似这样的东西?-http://jsfiddle.net/p6bnLdoq/,修改了
removeFromArray方法以避免循环并使用拼接方法 -
我不明白你目前的方法是
O(n²)。它是O(n*k),其中n是arrB中的项目数,k是arrayOfItems中的项目数。这种复杂性完全没问题。 -
您可能希望在
addToArray中省略indexOf。似乎已经确定arrA和arrB中都没有项目(并且您的算法保持该不变性),因此您不必在将项目从一个交换到另一个之前检查重复项 -
@AndrewLuhring: 是的,您可以使用
arrayOfItems的有效查找结构使其成为O(n+k),该结构不需要循环,但允许您在O(1)中确定一个项目是否应该是交换了。这样,通过arrB一次就足够了。但是,如果数组是有限的(并且非常小),那几乎没有关系
标签: javascript arrays performance time-complexity space-complexity