方法一:
使用最暴力的方法,每次取出数组最后一位,然后将所有元素一次向后移动一位,再将取出来的最后一位数字放在第一位,循环k次。时间复杂度为O(N^2),空间复杂度为O(1)。此方法会超出时间限制。
void rotate(int* nums, int numsSize, int k){
for(int j = 0; j < k % numsSize; j++)
{
int tmp = nums[numsSize - 1];
for(int i = numsSize - 1; i > 0; i--)
{
nums[i] = nums[i - 1];
}
nums[0] = tmp;
}
}
需要注意要将k求余运算,因为k大于数组长度之后,实际会将数组整体轮转一周,所有元素又会回到最初的位置,相当于没有轮转。
方法二:
开辟一个新的数组,大小和指定数组一致。首先将指定数组后k个元素放在新数组的前k个位置,然后再将指定数组剩余的元素放在新数组的k位置之后。最后将新数组拷贝到指定数组。时间复杂度为O(N),空间复杂度为O(N)。
代码1:
void rotate(int* nums, int numsSize, int k){
int arr[numsSize];
k %= numsSize;
for(int i = 0; i < k; i++)
{
arr[i] = nums[numsSize - k + i];
}
for(int i = k; i < numsSize; i++)
{
arr[i] = nums[i - k];
}
for(int i = 0; i < numsSize; i++)
{
nums[i] = arr[i];
}
}
代码2:
void rotate(int* nums, int numsSize, int k){
int* arr = (int*)malloc(sizeof(int) * numsSize);
k %= numsSize;
memcpy(arr, nums + numsSize - k, sizeof(int) * k);
memcpy(arr + k, nums, sizeof(int) * (numsSize - k));
memcpy(nums, arr, sizeof(int) * numsSize);
free(arr);
}
方法三:
可以先将数组后k个元素反转,再将数组前面的剩余元素反转,最后数组整体元素反转。
比如:数组[1,2,3,4,5,6],k=3
首先反转后k个元素:[1,2,3,6,5,4]
然后反转剩余元素:[3,2,1,6,5,4]
最后反转整个数组:[4,5,6,1,2,3]
void reverse(int* nums, int numsSize)
{
int tmp = 0;
for(int i = 0; i < numsSize / 2; i++)
{
tmp = nums[i];
nums[i] = nums[numsSize - i - 1];
nums[numsSize - i - 1] = tmp;
}
}
void rotate(int* nums, int numsSize, int k){
k %= numsSize;
reverse(nums, numsSize - k);
reverse(nums + numsSize - k, k);
reverse(nums, numsSize);
}