2016-09-21 375 views
-1

我一直在解決a hacker rank problem。它的想法是「向左」移動第一個索引元素n次。問題是當我的算法收到一個大數組時。在黑客等級服務器中產生超時問題。我不明白這個問題背後的問題。 任何人都知道發生了什麼?爲什麼JavaScript Array#shift或Array#slice會導致性能問題?

我試圖兩個想法

示例輸入

5 4 
1 2 3 4 5 

實施例輸出

5 1 2 3 4 

思想1

function processData(input) { 
    var input_arguments = input.split(/\n/), 
     rotations_count = parseInt(input_arguments[0].split(/\s/)[1],10), 
     array = input_arguments[1].split(/\s/); 

    while(rotations_count--){ 
     let value = array[0]; 
     array = array.slice(1); 
     array.push(value); 
    } 
    console.log(array.join(' ')); 
} 

Idea2

function processData(input) { 
    var input_arguments = input.split(/\n/), 
     rotations_count = parseInt(input_arguments[0].split(/\s/)[1],10), 
     array = input_arguments[1].split(/\s/); 

    while(rotations_count > 0){ 
     array.push(array.shift()); 
     rotations_count--; 
    } 
    console.log(array.join(' ')); 
} 
+1

首先,你犯了一個錯字,並使用'splice'而不是'slice'。 – Bergi

+1

使用'slice'或'shift'的時間解決方案的複雜度爲'O(d n)'。你應該能夠把它歸結爲'O(n)'。根據Hackerrank給出的「約束條件」,這意味着在最糟糕的情況下,不好的解決方案會慢10000倍。 – Bergi

+0

感謝您的指導。現在挑戰聽起來非常有趣! :D –

回答

0

你試圖輪班一個接一個的事,而是一個有效的解決方案會做一個大的轉變,一次全部。你所缺少的「問題」是輪班次數告訴你陣列中的哪一部分可以「剪切」成兩部分,然後你可以拿第一部分並將其添加到第二部分的末尾。使用他們的例子:

let array = [1, 2, 3, 4, 5]; 
let shifts = 4; 

// Create a temp array holding the values of 'array' up the shift point 
let temp = array.slice(0, shifts); 

// Delete the beginning of 'array' up to shift point 
// and add the temp array to the end of 'array' 
let newArray = array.splice(shifts).concat(temp); 

這就是它的全部。

+0

正確的想法,但如果「移位」是400?順便說一句,這段代碼不起作用。它返回'[5,5]'。我想你忘了'splice'返回已刪除的元素。 – 2016-09-21 05:29:28

+0

對不起,修正了錯字。它現在應該返回正確的結果。採用這種解決方案時,「移位」的大小沒有意義。您正在使用本地方法來一次性剪切並排列數組,而不是使用循環一次執行一次。我已經通過這個確切的解決方案在HackerRank上通過了挑戰。也許有一個更有效的解決方案,但這個爲我工作。 – skyline3000

+0

我不知道HackerRank正在使用什麼測試,但392的「移位」應該可以工作,但是不適合您的解決方案。 – 2016-09-21 05:45:18