2015-11-05 79 views
0

我正在练习算法,我正在做一个问题,你给了一个数组,并且你想返回一个数组,该指数。所以[1,2,3,4]会返回[24,12,8,6]。我的方法是遍历数组,创建一个副本,并拼接出当前索引,然后将该副本推送到输出数组。有效的方法来压扁数组元素(而不是整个数组)javascript

function getAllProductsExceptAtIndex(arr) { 
    var productArr = []; 

    for (var i = 0; i < arr.length; i++) { 
    var copy = arr.slice(); 
    copy.splice(i, 1); 
    productArr[i] = copy; 
    } 

    // return productArr; 
    for (var j = 0; j < productArr.length; j++) { 

    reduce(productArr[j]); 

    } 
} 

getAllProductsExceptAtIndex([1, 2, 3]); ---> productArr = [[2,3],[1,3],[1,2]] 

现在,你必须在它的正确值的输出阵列,它只是需要被“降低”与乘法一个值。现在减少groovy和所有,但在这种情况下,我试图有效率(时间),所以循环通过一个数组和减少将O(n)平方,因为减少内部使用for循环。我想写一个帮手来减少,但如果你在循环中调用它,它仍然是o(n)方形?

什么是一种更有效的方法来乘以productArr的每个索引内的元素,然后变平?宁愿不在解决方案中使用分工。

+0

在提供答案后,请不要改变您的问题。那是不好的行为。 – Amit

+0

我不知道该如何回答,但我也提供了一个不分裂的解决方案。也许你可以编辑这个问题,以便你更喜欢*不使用除法(并将其标记为事后考虑) - 至少这不会使答案看起来不相关。 – Amit

+0

当然,再次抱歉!将不会再发生 – devdropper87

回答

2

该解决方案从Interview Cake翻译为JS。强烈建议用于学习算法:https://www.interviewcake.com/

“要找到除了每个索引处的整数之外的所有整数的乘积,我们将两次贪婪地查看列表,首先我们得到每个索引之前的所有整数的乘积,然后我们向后得到每个索引后所有整数的乘积

当我们将每个索引前后的所有乘积相乘时,我们得到了我们的答案 - 除了每个整数之外的所有整数的乘积指数!”

function productOfInts(arr){ 
    var productOfAllExceptIndex = new Array(arr.length); 
    var productSoFar = 1; 

    for (var i = 0; i < arr.length; i++){ 
    productOfAllExceptIndex[i] = productSoFar; 
    productSoFar *= arr[i]; 
    } 

    productSoFar = 1; 

    i -= 1; 

    while (i >= 0){ 
    productOfAllExceptIndex[i] *= productSoFar; 
    productSoFar *= arr[i]; 
    i--; 
    } 

    return productOfAllExceptIndex; 
} 
+0

谢谢!什么是您“跳过”当前项目的机制? – devdropper87

+0

我不清楚当你计算产品之前,productSoFar * = arr [i];当你给这个函数输入一个输入[2,4,10] – devdropper87

+0

时,导致产品在[0] = 1之前,而不是产品在之前[0] = 2,我明白了 - 编辑你的答案以澄清我的困惑和解决方案的根源 – devdropper87

2

真的很简单:

function getAllProductsExceptAtIndex(arr) { 
 
    var product = arr.reduce(function(prev, curr) { return prev * curr; }); 
 
    return arr.map(function(v) { return product/v; }); 
 
} 
 

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

计算整个阵列的产物,然后映射每个值product/current_value,这是阵列的其余部分的产物。


如果你想不使用部门的解决方案,可以把mapreduce而忽略当前项目:

function getAllProductsExceptAtIndex(arr) { 
 
    return arr.map(function(v, i) { 
 
    return arr.reduce(function(prev, curr, j) { 
 
     return i != j ? prev * curr : prev; 
 
    }); 
 
    }); 
 
} 
 

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


最后,代码复杂一点,我们可以在O(n)的时间:

function getAllProductsExceptAtIndex(arr) { 
 
    if(arr.length === 0) 
 
    return []; 
 

 
    var i, products = [1]; 
 
    for(i = 0; i < arr.length - 1; i++) { 
 
    products.push(products[i] * arr[i]); 
 
    } 
 

 
    for(var t = 1; i >= 0; i--) { 
 
    products[i] *= t; 
 
    t *= arr[i]; 
 
    } 
 

 
    return products; 
 
} 
 

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

这里,我们计算产品在第一遍各指标的左侧,但我们使用先前的计算这样做(O(n))。然后我们做同样的事情,计算右边的乘积,然后乘以我们之前的计算结果。在边缘案例中插入了一个常量“” - 0项([0]的左侧,以及[length - 1]的右侧)的“产品”。

要了解其工作原理,请考虑左侧所有项目的产品由任何项目右侧的所有项目的产品复制的含义。

+0

“最后,代码复杂一点,我们可以做到这一点O(n)时间:“---第一个2行解决方案也是”O(N)“。 – zerkms

+0

@zerkms - 是的,但OP然后添加了一个不使用除法的约束。 – Amit

-1

对于数组/对象操作,您可以使用下划线或lodash https://lodash.com

// _.map : Produces a new array of values by mapping each value in list through a transformation function (iteratee) http://underscorejs.org/#map 
_.map([1,2,3], function(value, index, collection){ 
    return _.without(collection, value) 
}) // -> [[2,3],[1,3],[1,2]] 

,如果你喜欢这样的lib,还要检查is.js和字符串。js

相关问题