目录
一、题目说明
二、题目解析
一、题目说明
题目链接:leetcode旋转数组
给你一个数组,将数组中的元素向右轮转k个位置,其中k是非负数。
示例1:
输入:nums = [1,2,3,4,5,6,7],k = 3
输出:[5,6,7,1,2,3,4]
解释:
向右轮转1步:[7,1,2,3,4,5,6]
向右轮转2步:[6,7,1,2,3,4,5]
向右轮转3步:[5,6,7,1,2,3,4]
示例2:
输入:nums = [-1,-100,3,99],k = 2
输出:[3,99,-1,-100]
解释:
向右轮转1步:[99,-1,-100,3]
向右轮转2步:[3,99,-1,-100]
二、题目解析
方法1:
首先要创建一个临时数组tmp[ ]
第一步:先将后k个数字拷贝到前面;
第二步:在将前n-k个数字拷贝到后面;
第三步:最后将临时数组里面的元素拷贝回去。
注意:为了保证逆置的次数k小于数组的大小,要在开头的位置先模等一下数组的大小。
void rotate(int* nums, int numsSize, int k)
{
k %= numsSize;
//变长数组
int tmp[numsSize];
//后k个拷贝前面
int j = 0;
for (int i = numsSize - k; i < numsSize; ++i)
{
tmp[j] = nums[i];
++j;
}
//前n-k个拷贝后面
for (int i = 0; i < numsSize - k; ++i)
{
tmp[j] = nums[i];
++j;
}
//拷贝回去
for (int i = 0; i < numsSize; ++i)
{
nums[i] = tmp[i];
}
}
时间复杂度为:O(N)。
方法2:
这种方法比较简单巧妙,但是先要自己编写一个逆置函数,
第一步:逆置前n-k个数字;
第二步:逆置后k个数字;
第三步:整体逆置。
注意:为了保证逆置的次数k小于数组的大小,要在开头的位置先模等一下数组的大小。
void reverse(int* nums, int begin, int end)
{
while (begin < end)
{
int tmp = nums[begin];
nums[begin] = nums[end];
nums[end] = tmp;
begin++;
end--;
}
}
void rotate(int* nums, int numsSize, int k)
{
k %= numsSize;
reverse(nums, 0, numsSize - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, numsSize - 1);
}
时间复杂度为:O(N)。
本文提供了两种方法,应该还有其他的最优解,欢迎大家在下面评论,互相帮助共同提高。
本文要是有不足的地方,欢迎大家在下面评论,我会在第一时间更正。