2015-11-05 39 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

相關問題