目录
题目来源
189. 轮转数组 - 力扣(LeetCode)https://leetcode.cn/problems/rotate-array/submissions/
函数介绍
给你一个数组,将数组中的元素向右轮转
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(旋转k次)
每次旋转一个数字(最后一个数字旋转到最前面),旋转k次
时间复杂度:O(n*k)
代码实现
void rotate(int* nums, int numsSize, int k)
{
while (k--)
{
int temp = nums[numsSize - 1];
for (int end = numsSize - 2; end >= 0; --end)
{
nums[end + 1] = nums[end];
}
nums[0] = temp;
}
}
函数实现2(以空间换时间)
1、划分旋转区域,将数组划分为两个区域
前区域:需要旋转到右边的所有数(头部需要旋转到尾部的元素)
后区域:需要旋转到左边的所有数(尾部需要旋转到头部的元素)
2、迁移数据到辅助数组
先迁移后区域,再迁移前区域
3、拷贝回原数组时间复杂度,空间复杂度O(n)
代码实现
void rotate(int* nums, int numsSize, int k)
{
int a[100];
int j=0;
for (int i = numsSize - k; i <numsSize ; i++)
{
a[j] = nums[i];
j++;
}
j = 3;
for (int i = 0; i < numsSize -k; i++)
{
a[j] = nums[i];
j++;
}
for (int i = 0; i < numsSize ; i++)
{
nums[i] = a[i];
}
}
函数实现3(三次反转)
1、后k个逆置
2、前n-k个逆置
3、整体逆置
代码实现
void Reverse(int* nums, int left, int right)
{
while (left < right)
{
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
right--;
left++;
}
}
void rotate(int* nums, int numsSize, int k)
{
if (k > numsSize)
k = k%numsSize;
Reverse(nums, numsSize-k, numsSize-1);
Reverse(nums, 0, numsSize-k-1);
Reverse(nums, 0, numsSize-1);
}
用法示例
#include<stdio.h>
//思路一:旋转k次
// 时间复杂度:O(n*k)
//void rotate(int* nums, int numsSize, int k)
//{
// while (k--)
// {
// int temp = nums[numsSize - 1];
// for (int end = numsSize - 2; end >= 0; --end)
// {
// nums[end + 1] = nums[end];
// }
// nums[0] = temp;
// }
//}
// //思路二:以空间换时间
//时间复杂度,空间复杂度O(n)
//void rotate(int* nums, int numsSize, int k)
//{
// int a[100];
// int j=0;
// for (int i = numsSize - k; i <numsSize ; i++)
// {
// a[j] = nums[i];
// j++;
// }
// j = 3;
// for (int i = 0; i < numsSize -k; i++)
// {
// a[j] = nums[i];
// j++;
// }
// for (int i = 0; i < numsSize ; i++)
// {
// nums[i] = a[i];
// }
//}
//思路三:
//1、后k个逆置
//2、前n-k个逆置
//3、整体逆置
void Reverse(int* nums, int left, int right)
{
while (left < right)
{
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
right--;
left++;
}
}
void rotate(int* nums, int numsSize, int k)
{
if (k > numsSize)
k = k%numsSize;
Reverse(nums, numsSize-k, numsSize-1);
Reverse(nums, 0, numsSize-k-1);
Reverse(nums, 0, numsSize-1);
}
int main()
{
int nums[7] = { 1,2,3,4,5,6,7 };//numsSize=7
int size =7;
int k = 3;
rotate(nums, size, k);
for (int i = 0; i < size; i++)
{
printf("%d ", nums[i]);
}
return 0;
}