1.题目
今天来简要介绍一下为什么在力扣上用基础解法无法过案例
有题目容易得知我们需要对函数需要进行什么设计,接下来就是一些具体解法
2.题解
2.1题解一
基础解法,封装为函数后,通过对原来的数组进行双循环,时间复杂度为O(N^2),空间复杂度为O(1),因为时间复杂度大,会使一些案例程序运行超过时间
#include <stdio.h>
int main()
{
int arr[7] = { 1,2,3,4,5,6,7 };
int i = 0;
int n = 0;
int j = 0;
scanf_s("%d", &n);//轮转n次
int t = 0;
for (j = 0; j < n; j++)
{
int t = arr[6];
for (int i = 5; i >= 0; i--)
arr[i + 1] = arr[i];
arr[0] = t;
}
for(int k =0;k<6;k++)
printf("%d", arr[k]);
}
2.2题解二
进阶解法,通过牺牲了空间来使程序运行的效率变高,时间复杂度为O(N),空间复杂度为O(N)。经过细微修改可以通过力扣轮转数组上的所有案例,此法不仅包含了向右轮转,还包括了向左轮转
#include <stdio.h>
//轮转数组的优化写法,向右和向左轮转,时间复杂度O(N)
void rotate(int* arr, int length, int k)
{
int newarr[7];//其实这里7应该放成length,表示的是数组的长度,但VS2022不支持在数组下标是变量
for (int i = 0; i < length; i++)
{
newarr[(i + k) % length] = arr[i];//向右轮转,核心步骤,直接将要轮转的那一段数组放在新数组前面,后面再接剩余部分
//newarr[(i%length+length-k)%length] = arr[i];//向左轮转,核心步骤,直接将要轮转的那一段数组放在新数组前面,后面再接剩余部分
}
for (int i = 0; i < length; i++)
{
arr[i] = newarr[i];//将新数组重新覆盖到原数组
}
return;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7 };
int length = sizeof(arr) / sizeof(arr[0]);
rotate(arr, 7,3);
for(int i =0;i<length;i++)
printf("%d ",arr[i]);
}
2.3题解三
轮转数组的T3版本
首先设计一个函数revser,可以实现将数组整体逆序。接下来先分别使前n-k个数组内容逆序,后k个数组逆序,再对两次逆序后的数组整体逆序就得到向右轮转数组k次结果。此题解最为简单,逆序函数设计简单,只需调用三次函数即可,且能通过力扣的题解案例
接下来介绍一下是如何完成向右轮转k个数据的操作
初始时的数组:
1 | 2 | 3 | 4 | 5 | 6 | 7 |
前n-k个数组内容逆序:
4 | 3 | 2 | 1 | 5 | 6 | 7 |
后k个数组逆序:
4 | 3 | 2 | 1 | 7 | 6 | 5 |
整体逆置:
5 | 6 | 7 | 1 | 2 | 3 | 4 |
这样就达到了向右轮转k个位置的效果
#include <stdio.h>
//轮转数组03版本
void revser(int* nums, int right, int left)//逆置数组
{
int t = 0;
while (right < left)
{
t = nums[right];
nums[right] = nums[left];
nums[left] = t;
right++;
left--;
}
}
void rotate2(int* nums, int numSize, int k)
{
k = k % numSize;//使k不超过数组的大小
revser(nums, 0, numSize - k - 1);//逆置前n-k个数组
revser(nums, numSize-k, numSize - 1);//逆置后k个数组
revser(nums, 0, numSize - 1);//整体逆置数组
for (int i = 0; i < numSize; i++)
{
printf("%d ", nums[i]);
}
}
int main()
{
int arr[7] = { 1,2,3,4,5,6,7 };
int length = sizeof(arr) / sizeof(arr[0]);
rotate2(arr, length, 3);
}
3.总结
题解二运行效率最高,比较推荐,但是运行的核心代码稍稍复杂,需要记忆:题解三最为简单,且能通过案例,但需设计两个函数,代码函数更多,效率更低一点点,但是优势是简单,也比较推荐。看个人需要,建议题解二,代码行数更少,效率更高。
文末附上力扣题目:. - 力扣(LeetCode)