轮转数组
暴力求解
取数+挪动
取数:将数组最后一个数字取出;——K次
挪动:将数组前面的数往后挪动一位;——N次
因为K最大可能等于N,所以这种方法的时间复杂度是O(N^2),太慢了。在力扣的编译器跑不过去
空间换时间
开辟新数组arr,将nums中后k个数依次放到新数组arr中,再依次将nums中前n-k个数放进arr中。
思路很简单,但实现起来比较难想到,属于是找规律了,
nums的下标和arr的下标应该是要有一定的算术关系的,
以n=7,k=3为例,如图
时间复杂度位O(N),空间复杂度为O(N)。
void rotate(int* nums, int numsSize, int k){
int* arr = (int*)malloc(numsSize*sizeof(int));
for(int i = 0; i < numsSize; i++){
arr[(i+k) % numsSize] = nums[i];
}
for(int i = 0; i < numsSize; i++){
nums[i] = arr[i];
}
}
双重逆置
将数组前n-k个数逆置,后k个数逆置,再整体逆置,即可。
逆置函数用双指针实现。
void reverse(int *p, int lf, int rg){
while(lf < rg){
int tmp = p[lf];
p[lf] = p[rg];
p[rg] = tmp;
lf++;
rg--;
}
}
void rotate(int* nums, int numsSize, int k){
k = k%numsSize; //当k>numsSize时,需将多出的x倍的numsSize除掉。
reverse(nums, numsSize-k, numsSize-1);
reverse(nums, 0, numsSize-k-1);
reverse(nums, 0, numsSize-1);
}