<C语言>——轮转数组

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个数据的操作

初始时的数组:

1234567

前n-k个数组内容逆序:

4321567

后k个数组逆序:

4321765

整体逆置:

5671234

这样就达到了向右轮转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)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jc导航键

感谢您的认可,这是我更新的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值