给你一个数组,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
输入: 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]来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/rotate-array
注意 k %= numsSize; 因为翻转一个numsSize大小的轮回,数组未变!
注释代码的时间和空间复杂度分别为: O(k*N) 和 O(1);
翻转的时间和空间复杂度分别为: O(1) 和 O(1);
void rotate(int* nums, int numsSize, int k)
{
// 法1
k %=numsSize;
int left =0;
int right = numsSize-k-1;
while(left<=right)
{
int tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
left++;
right--;
}
left = numsSize-k;
right = numsSize-1;
while(left<=right)
{
int tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
left++;
right--;
}
left = 0;
right = numsSize-1;
while(left<=right)
{
int tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
left++;
right--;
}
//法2
// 空间复杂度: O(k)
// 数组最后一个元素前移至第一个元素,移 K 次
// int i = 0;
// int tmp = 0;
// int j = 0;
// 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;
// }
}
还有一种方法是以空间换时间:额外开辟一个数组,把原数组的后K个值拷贝到开辟数组的前k个,把原数组的前K个值拷贝到开辟数组的后k个,然后拷贝整个新开辟数组覆盖原数组;此法的时间和空间复杂度分别为: O(N) 和 O(N);
void rotate(int* nums, int numsSize, int k)
{
// 法3
k %= numsSize;
int tmp[numsSize];
// 后k个拷贝到前面
int j = 0;
for(int i = n-k; i<n; ++i)
{
tmp[j] = nums[i];
++j;
}
// 前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];
}
}