一.题目描述
二.题目分析
k只说是非负数,没说具体范围,万一所旋转次数大于nums数组内容时就得另当别论
解决办法:k=k%numsSize
三.题目解决
1.旋转一次:下标为numsSize-1的数值单独放在一个tmp变量中,后面数据依次往前挪动数据,之后再把tmp放在最前面,就完成了一次数据旋转,一共旋转k此就可以
代码如下
void rotate(int* nums, int numsSize, int k)
{
if(k>=numsSize)
{
k=k%numsSize;
}
int i=0;
//k次旋转
while(k--)
{
//下标为numsSize-1的数值单独放在一个tmp变量中
int tmp=nums[numsSize-1];
//面数据依次往前挪动数据
for(i=numsSize-2;i>=0;i--)
{
nums[i+1]=nums[i];
}
//tmp放在最前面
nums[0]=tmp;
}
}
分析可得:时间复杂度为O(n^2),空间复杂度为O(1)
可不可以优化时间复杂度呢?
2.开辟一个新空间,先将后k个拷贝过来,再将剩下的数据拷贝过来,最后把数据拷贝会原数组中
这里就有就两种开辟空间的方法;
a.开辟数组
b.动态开辟
a.代码实现
void rotate(int* nums, int numsSize, int k)
{
//开辟空间,leetcode支持变长数组
int arr[numsSize];
if(k>=numsSize)
{
k=k%numsSize;
}
int i=0;
//数据拷贝新空间中
for(i=0;i<k;i++)
{
arr[i]=nums[numsSize-k+i];
}
int j=0;
for(j=0;j<numsSize-k;j++)
{
arr[i]=nums[j];
i++;
}
//新空间数据拷贝会nums数组
for(int ch=0;ch<numsSize;ch++)
{
nums[ch]=arr[ch];
}
}
b.代码实现
在这里插入代码片void rotate(int* nums, int numsSize, int k)
{
//动态开辟
int*arr=(int*)malloc(sizeof(int)*numsSize);
if(arr==NULL)
{
perror("malloc fail");
exit(-1);
}
//数据拷贝新空间中
if(k>=numsSize)
{
k=k%numsSize;
}
int i=0;
for(i=0;i<k;i++)
{
arr[i]=nums[numsSize-k+i];
}
int j=0;
for(j=0;j<numsSize-k;j++)
{
arr[i++]=nums[j];
}
//新空间数据拷贝会nums数组
for(int ch=0;ch<numsSize;ch++)
{
nums[ch]=arr[ch];
}
//释放空间
free(arr);
arr=NULL;
}
动态开辟不要忘记用完了释放空间
空间复杂度为O(n),时间复杂度O(n)
可不可以继续优化呢?
3. 先将前numsSize-k个数据逆置,后将后k个数据逆置,最后把整个数组逆置
代码实现
void reverse(int*nums,int left,int right)
{
while(left<=right)
{
int tmp=nums[left];
nums[left]=nums[right];
nums[right]=tmp;
left++;
right--;
}
}
void rotate(int* nums, int numsSize, int k)
{
if(k>=numsSize)
{
k=k%numsSize;
}
//numsSize-k个数据逆置
reverse(nums,0,numsSize-k-1);
//将后k个数据逆置
reverse(nums,numsSize-k,numsSize-1);
//整个数组逆置
reverse(nums,0,numsSize-1);
}
以上代码仅供参考 如有错误请大家指点 我会尽快去改正 欢迎大家来评论~~~