一开始我对数组slice
和concat
的复杂度存在误解,我认为他们都是O(n)的时间复杂度,因为相当于是把原数组(某个部分或者全部)数据一个一个加到新数组上面,老师讲他们都是O(1)的,我很好奇.
所以我按照自己的想法把slice
和concat
实现了一下,代码如下:
function mySlice(arr: number[], start: number, end: number) {
const newArr = [];
for (let i = start; i <= end; ++i) {
newArr.push(arr[i]);
}
return newArr;
}
function myConcat(arr1: number[], arr2: number[]) {
const newArr = [];
for (let i = 0; i < arr1.length; i++) {
const element = arr1[i];
newArr.push(element);
}
for (let i = 0; i < arr2.length; i++) {
const element = arr2[i];
newArr.push(element);
}
return newArr;
}
这个实现的复杂度很明显是O(n)的嘛. 然后我用自己写的这两个API替换掉原数组的API.
export function rotate3(arr: number[], k: number): number[] {
const length = arr.length;
const step = Math.abs(k % length);
if (!step || !length) {
return arr;
}
const part1 = mySlice(arr, length - step, length - 1);
const part2 = mySlice(arr, 0, length - step - 1);
const part3 = myConcat(part1, part2);
return part3;
}
这段代码也是通过了单元测试的,然后进行性能测试的时候.它的用时是6ms,而用了原生API的算法的用时是0.5ms,显然不是一个数量级,所以原生的复杂度肯定不是O(n),应该是O(1),
所以,为什么原生的slice
和concat
复杂度是O(1)的,可以解释一下吗?