将一个数组旋转 k 步


问题 1:输入一个数组 [1,2,3,4,5,6,7],k=3,即旋转 3 步,输出 [5,6,7,1,2,3,4]

思路 1:把末尾的元素挨个 pop ,然后 unshift 到数组前面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function rotateArray(arr, k) {
const length = arr.length;
if (!k || length === 0) return arr;
k = Math.abs(k % length);
for (let i = 0; i < k; i++) {
const lastElement = arr.pop();
arr.unshift(lastElement);
}
return arr;
}

const inputArray = [1, 2, 3, 4, 5, 6, 7];
const k = 3;
const rotatedArray = rotateArray(inputArray, k);
console.log(rotatedArray); // Output: [5, 6, 7, 1, 2, 3, 4]

思路 2:把数组拆分,最后 concat 拼接到一起

1
2
3
4
5
6
7
8
9
10
11
12
13
function rotateArray(arr, k) {
const length = arr.length;
if (!k || length === 0) return arr;
k = Math.abs(k % length); // Handle cases where k is greater than the array length
const firstPart = arr.slice(0, length - k);
const secondPart = arr.slice(length - k);
return secondPart.concat(firstPart);
}

const inputArray = [1, 2, 3, 4, 5, 6, 7];
const k = 3;
const rotatedArray = rotateArray(inputArray, k);
console.log(rotatedArray); // Output: [5, 6, 7, 1, 2, 3, 4]

让我们来分析以上两种思路的时间复杂度和空间复杂度:

思路 1:

时间复杂度:在该思路中,我们需要进行 k 次旋转操作。每次旋转操作都需要将末尾元素移除,并将其添加到数组的前面。pop 和 unshift 操作的时间复杂度都是 O(1)。因此,总体时间复杂度为 O(k)。
空间复杂度:在原地进行操作,没有使用额外的辅助数组或数据结构,因此空间复杂度为 O(1),即为常数空间复杂度。

思路 2:

时间复杂度:在该思路中,我们需要进行一次 slice 操作和一次 concat 操作。slice 操作的时间复杂度为 O(n),其中 n 是数组的长度。concat 操作的时间复杂度也是 O(n),因为它需要遍历并拼接两个数组。因此,总体时间复杂度为 O(n)。
空间复杂度:在该思路中,我们使用了两个辅助数组,分别存储前部分和后部分的元素,因此空间复杂度为 O(n),其中 n 是数组的长度。这里的空间复杂度主要由两个辅助数组的大小决定。

综上所述,思路 1 的时间复杂度为 O(k),空间复杂度为 O(1);而思路 2 的时间复杂度为 O(n),空间复杂度为 O(n)。通常情况下,如果 k 的值较小且不与数组的长度相关,那么思路 1 的效率会更高。但是,如果 k 的值较大,接近或大于数组的长度,那么思路 2 的效率会更高,因为它只需要进行一次数组拼接操作。

亮点
写单元测试