📅  最后修改于: 2023-12-03 15:22:24.058000             🧑  作者: Mango
在程序开发中,有时候需要对给定的数组进行右旋转(也称为循环移位),即将数组的最后 k 个元素移动到数组的开头,而前面的元素则向后移动 k 个位置。使用指针可以更加高效地完成这个任务。
我们可以先将整个数组翻转一下,然后再将前 k 个元素翻转,最后将后面的元素翻转,就可以实现数组向右旋转 k 次的效果。
举个例子,假如给定的数组是 [1,2,3,4,5,6,7]
,k=3,翻转后的结果是 [7,6,5,4,3,2,1]
,然后我们再将前面 k 个元素翻转得到 [5,6,7,4,3,2,1]
,最后再将后面的元素翻转得到 [5,6,7,1,2,3,4]
。这正是我们要求的结果。
我们可以使用指针来实现这个过程,具体的代码实现如下所示。首先定义一个辅助函数 reverse
,用于翻转一个数组中指定范围内的元素。然后再使用三次翻转分别实现整个数组、前面 k 个元素和后面的元素的翻转。最后我们就可以得到向右旋转 k 次后的数组了。
void reverse(int* nums, int start, int end) {
while(start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
void rotate(int* nums, int numsSize, int k){
k = k % numsSize;
reverse(nums, 0, numsSize - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, numsSize - 1);
}
这个算法的时间复杂度为 O(n),其中 n 是数组的长度。虽然算法中使用了三次翻转操作,但每个元素最多会被翻转两次,因此总共最多执行 2n 次操作。
空间复杂度为 O(1),因为我们并不需要额外的空间来进行操作。