力扣https://leetcode.cn/problems/rotate-array/
这题主要是需要三种方法解决。
法一:
第一种就是最常规的方法,保存最后一个数字,然后挪动数组,再将保存的数字给第一位。
法一:常规法 O(N^2)
void right_round(int arr[], int sz,int k)
{
k %= 7;
int i = 0;
for (i = 0; i < k; ++i)
{
int j;
int end = arr[sz-1];
for (j = sz-1; j >0 ; --j)
{
arr[j] = arr[j-1];
}
arr[0] = end;
}
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7 };
int sz = sizeof(arr) / sizeof(arr[0]);
int k = 0;
scanf("%d", &k);
right_round(arr, sz,k);
int i = 0;
for (i = 0; i < sz; ++i)
{
printf("%d ", arr[i]);
}
return 0;
}
这种方法时间复杂度是O(N^2)。注意:不是O(K*N),因为k>=N的时候就相当于数组轮转了一轮的基础上又重新开始旋转,所以k % N的,因此,k的最大为N-1,时间复杂度考虑最坏的情况,所以是O(N^2)。
法二:
这种方法是新开辟一个数组,借用这个数组将轮转后的结果放到数组中,再把结果放回原数组中,最后释放开辟的数组。实际上是一种空间换时间的方法。时间复杂度O(N)
法二:开辟新数组存放(空间换时间)
#include<errno.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7 };
int sz = sizeof(arr) / sizeof(arr[0]);
int k = 0;
scanf("%d", &k);
k %= 7;
int* p = (int*)malloc(sizeof(int) * sz);
if (p == NULL)
{
perror("p");
return -1;
}
int n = 0;
for (int m = sz - k; m < sz; ++m)
{
p[n++] = arr[m];
}
for (int a = 0; a < sz - k; ++a)
{
p[n++] = arr[a];
}
for (int b = 0; b < sz; ++b)
{
arr[b] = p[b];
}
free(p);
p = NULL;
int i = 0;
for (i = 0; i < sz; ++i)
{
printf("%d ", arr[i]);
}
return 0;
}
法三:
这种方法一般是见过了才能想到,逆置三次数组
时间复杂度O(N)
法三:三次逆置
#include<assert.h>
void reverse(int* begin, int* end)
{
assert(begin && end);
while (begin < end)
{
int tmp = *begin;
*begin = *end;
*end = tmp;
begin++;
end--;
}
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7 };
int sz = sizeof(arr) / sizeof(arr[0]);
int k = 0;
scanf("%d", &k);
k %= sz;
reverse(arr, arr + sz-k-1);
reverse(arr+sz-k, arr + sz-1);
reverse(arr, arr + sz-1);
for (int i = 0; i < sz; ++i)
{
printf("%d ", arr[i]);
}
return 0;
}