题目描述:
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
示例:
题目链接:https://leetcode.cn/problems/rotate-array/
解题思路:
思路一
思路一: 每次记录下数组最后一个值,再将数组中元素从后往前向依次后移一位,再将记录下来的值放到数组的首元素位置,执行k次。
解法图示:
但这样写出来的代码的时间复杂度为O(N^2),在力扣上跑不过,所以参考一下就行。
思路二
思路二: 创建一个额外数组。因为我们要轮转原数组的后k个元素,所以轮转后的数组中的前k个元素就是轮转前数组中的后k个元素。所以我们就可以先将原数组中的后k个元素拷贝到新创建数组中的前k个位置处,然后再将原数组中剩余元素拷贝到新创建数组中的剩余位置,再将新创建数组中元素依次拷贝回原数组中即可。
解法图示:
思路三
思路三: 三次逆转法:
1.先将整个数组逆转;
2.再将nums中的子数组下标为[0—(k-1)]逆转;
3.再将nums中的剩余的子数组下标为[k—(size-1)]逆转。
解法图示:
示例代码
思路一:
思路一:
void rotate(int* nums, int numsSize, int k) {
int i,j,tmp;
for(i=0;i<k;i++)
{
tmp=nums[numsSize-1];
for(j=numsSize-1;j>0;j--)
{
nums[j]=nums[j-1];
}
nums[0]=tmp;
}
}
注意: 这个代码过不了(时间复杂度O(N^2)),参考一下就行了。
思路二:
思路二:
//方二:使用额外的数组
void rotate(int* nums, int numsSize, int k) {
int arr[numsSize];
int i=0;
for(i=0;i<numsSize;i++)//将每个元素按要求放到新数组中
{
arr[(i+k)%numsSize]=nums[i];
}
for(i=0;i<numsSize;i++)//再将新数组中元素遍历赋值到题干数组中
{
nums[i]=arr[i];
}
}
补充: 在上述代码中当k>numsSize时,其实就不用轮转k次了,只需要轮转k%numsSize就可以了,多余的都是重复轮转。
思路三:
思路三:
//逆转函数
void reverse(int* nums,int begin,int end)
{
int tmp;
while(begin<end)
{
tmp=nums[end];
nums[end]=nums[begin];
nums[begin]=tmp;
begin++;
end--;
}
}
void rotate(int* nums, int numsSize, int k) {
//方法三:三次逆转法
//当k>numsSize时去除多余的重复轮转
if(k>numsSize)
{
k=k%numsSize;
}
reverse(nums,0,numsSize-1);//全部逆转
reverse(nums,0,k-1);//逆转下标为0---(k-1)的元素
reverse(nums,k,numsSize-1);//逆转下标为k---(numsSize-1)的元素
}