我试图找出执行以下任务的最快方法:
编写一个接受两个数组作为参数的函数 - 每个数组都是一个排序的,严格升序的整数数组,并返回一个新的严格上升的整数数组,其中包含来自两个输入数组的所有值。
EG。合并[1,2,3,5,7]和[1,4,6,7,8]应该返回[1,2,3,4,5,6,7,8]。
由于我没有正式的编程教育,我的算法和复杂性有点陌生:)我已经有2个解决方案,但我不确定哪个更快。
解决方案1(它实际上使用第一个数组而不是创建一个新数组):
function mergeSortedArrays(a, b) {
for (let i = 0, bLen = b.length; i < bLen; i++) {
if (!a.includes(b[i])) {
a.push(b[i])
}
}
console.log(a.sort());
}
const foo = [1, 2, 3, 5, 7],
bar = [1, 4, 6, 7, 8];
mergeSortedArrays(foo, bar);
和解决方案2:
function mergeSortedArrays(a, b) {
let mergedAndSorted = [];
while(a.length || b.length) {
if (typeof a[0] === 'undefined') {
mergedAndSorted.push(b[0]);
b.splice(0,1);
} else if (a[0] > b[0]) {
mergedAndSorted.push(b[0]);
b.splice(0,1);
} else if (a[0] < b[0]) {
mergedAndSorted.push(a[0]);
a.splice(0,1);
} else {
mergedAndSorted.push(a[0]);
a.splice(0,1);
b.splice(0,1);
}
}
console.log(mergedAndSorted);
}
const foo = [1, 2, 3, 5, 7],
bar = [1, 4, 6, 7, 8];
mergeSortedArrays(foo, bar);
有人可以帮助我解决这两种解决方案的时间复杂性吗?还有,还有另一个更快的解决方案吗?我应该使用reduce()吗?
答案 0 :(得分:0)
你修改传递参数的第一个函数,这是不好的做法。 您可以通过以下方式完成此操作:
function mergeSortedArrays(a, b) {
return a.concat(b.filter(el => !a.includes(el))).sort();
}
答案 1 :(得分:0)
复杂性还取决于您在代码中使用的方法。
1)常用于排序的算法是Quicksort(作为快速排序的变种进行内省)。
它具有O(n log n)复杂度,但是在输入已经排序的情况下,最坏情况可能仍然是O(n ^ 2)。所以你的解决方案有O(长度(b)+长度(a)+长度(b)log(长度(a)+长度(b)))运行时复杂度。
2)根据complexity of splice()上的这个问题,javascript函数最坏的情况是需要O(n)步(将所有元素复制到大小为n + 1的新数组)。所以你的第二个解决方案需要数组b 的长度乘以在拼接期间复制元素所需的n个步骤加上push()的时间。
对于在线性时间O(n + m)工作的好解,请参考此Java example并将其移植(即创建一个大小长度(a)+长度(b)的数组并通过indeces步进如图所示)。或者在答案的下方查看非常紧凑甚至更快的实现。