我正在使用1,000,000个数字进行测试,这只是一种悬念。我认为它很容易轻松通过1,000,000。这是我的实施吗?我有一种感觉,因为slice()
,任何人都有想法?
编辑:
刚收到这条消息:
FATAL ERROR: CALL_AND_RETRY_2 Allocation failed - process out of memory
TopDownSplitMerge(numbersArray);
function TopDownSplitMerge(arrayOfNumbers) {
var length = arrayOfNumbers.length
var middleIndex = parseInt(length/2);
if(length <= 1) {
return arrayOfNumbers;
}
// Split left side
var left = TopDownSplitMerge(arrayOfNumbers.slice(0, middleIndex));
// Split right side
var right = TopDownSplitMerge(arrayOfNumbers.slice(middleIndex, length));
// Merge every back together
return TopDownMerge(left, right);
}
function TopDownMerge(left, right) {
var results = []
while(left.length || right.length) {
console.log("looping...");
// Check if both sides are NOT empty, if so, then just finish shifting the non-empty side
if(left.length && right.length) {
if(left[0] <= right[0]) {
results.push(left.shift())
} else {
results.push(right.shift())
}
} else if(left.length) {
results.push(left.shift())
} else {
results.push(right.shift())
}
}
console.log("Merging....", results.length);
return results;
}
答案 0 :(得分:2)
我认为你是对的。 slice()
复制数组,因此您可以有效地复制几十亿次数组。然后你的shift
从阵列前面开始,这需要每次复制阵列 - 多次数次。更好的方法是传递“分裂”的索引范围。
答案 1 :(得分:2)
我必须改变两件事
var right = TopDownSplitMerge(arrayOfNumbers.slice(middleIndex, length));
....
....
....
function TopDownMerge(left, right) {
var results = [], leftLen = left.length, rightLen = right.length;
for (var i = 0, j = 0; i < leftLen || j < rightLen;) {
if (i < leftLen && j < rightLen) {
if(left[i] <= right[j]) {
results.push(left[i]);
i += 1;
} else {
results.push(right[j]);
j += 1;
}
} else if (i < leftLen) {
results.push(left[i]);
i += 1;
} else {
results.push(right[j]);
j += 1;
}
}
return results;
}
编辑:现在我将其更改为接受索引而不是切片数组,这会提升性能。
function TopDownSplitMerge(arrayOfNumbers, start, end) {
var length = end - start;
var middleIndex = start + parseInt(length / 2);
if (length <= 1) {
return [arrayOfNumbers[start]];
}
// Split left side
var left = TopDownSplitMerge(arrayOfNumbers, start, middleIndex);
// Split right side
var right = TopDownSplitMerge(arrayOfNumbers, middleIndex, length);
// Merge every back together
return TopDownMerge(left, right);
}
TopDownSplitMerge(numbersArray, 0, numbersArray.length);
Jsperf:http://jsperf.com/so-q-19341534
jsperf for my solutions with 10,000,000 numbers:http://jsperf.com/solution-to-so-q-19341534