给定一个整数数组 nums
,将数组中的元素向右轮转 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]
输入: nums = [-1,-100,3,99], k = 2
输出: [3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
1 <= nums.length <= 10⁵
-2³¹ <= nums[i] <= 2³¹ - 1
0 <= k <= 10⁵
void rotate(int* nums, int numsSize, int k)
{
//空间换时间
k = k % numsSize;
int newArr[numsSize];
//现将nums后面的K个数据按顺序放到newArr中去,再把剩下的数据按顺序插入到新数组中
for(int i = 0; i < numsSize; i++)
{
newArr[i] = nums[(numsSize - k + i)%numsSize];
}
//因为最后需要打印数组nums,所以需要赋值回去
for(int i = 0; i < numsSize; i++)
{
nums[i] = newArr[i];
}
}
**结果:**不通过,时间复杂度过高,为 O ( N 2 ) O(N^2) O(N2)
void rotate(int* nums, int numsSize, int k)
{
//空间换时间
k = k % numsSize;
int newArr[numsSize];
//现将nums后面的K个数据按顺序放到newArr中去,再把剩下的数据按顺序插入到新数组中
for(int i = 0; i < numsSize; i++)
{
newArr[i] = nums[(numsSize - k + i)%numsSize];
}
//因为最后需要打印数组nums,所以需要赋值回去
for(int i = 0; i < numsSize; i++)
{
nums[i] = newArr[i];
}
}
void rotate(int* nums; int numsSize; int k)
{
int newArr[numsSize];
for(int i = 0; i < numsSize; i++)
{
newArr[(i + k) % numsSize] = nums[i];//将后K个数组放到新数组前面,在把剩下的挪到新数组
}
for (int i = 0; i < numsSize; ++i)
{
nums[i] = newArr[i];//因为最后需要打印数组nums,所以需要赋值回去
}
}
以上两组代码的代码逻辑基本一致,主要是在将数据移动到新数组时的具体实现思路不同。
//法一
k = k % numsSize;
newArr[i] = nums[(numsSize - k + i)%numsSize];
//法二
newArr[(i + k) % numsSize] = nums[i];
/*
函数功能:实现一段数据的逆置
参数:
nums:数组名
begin:逆置数据的起始下标
end:逆置数据的结束下标
返回值:无
*/
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 = k%numsSize;
//前n-k个数据逆置
reverse(nums,0,numsSize-k-1);
//后k个数据逆置
reverse(nums,numsSize-k,numsSize-1);
//整体逆置
reverse(nums,0,numsSize-1);
}
时间复杂度: O ( N ) O(N) O(N)
空间复杂度: O ( 1 ) O(1) O(1)
方法:
- 前n - k个逆置:4 3 2 1 5 6 7
- 后k个逆置:4 3 2 1 7 6 5
- 整体逆置:5 6 7 1 2 3 4