轮转数组.

力扣链接

题目

给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

思路一

假设数组为nums = {1, 2, 3, 4, 5, 6, 7}
1、先把最后一个元素拿出来
int tmp = *(nums + numsSize - 1);

在这里插入图片描述

2、把倒数第二个元素往后移一个位置
int end = numsSize - 2;

在这里插入图片描述

nums[end + 1] = nums[end];

在这里插入图片描述

把6挪过去后,再让end指向5,同样往后挪

在这里插入图片描述

3、重复上述过程,直到把7之前的所有元素都移位完成,再把7放到首位

int tmp = *(nums + numsSize - 1);
for (int end = numsSize - 2; end >= 0; end--)
{
	nums[end + 1] = nums[end];
}
nums[0] = tmp;

这样就将数组中的元素向右轮转 1 个位置

如果要轮转 k 次,加上循环即可

void rotate(int* nums, int numsSize, int k)
{
	while (k--)
	{
		int tmp = *(nums + numsSize - 1);
		for (int end = numsSize - 2; end >= 0; end--)
		{
			nums[end + 1] = nums[end];
		}
		nums[0] = tmp;
	}
}

运行一下,发现跑不过,因为测试用例中,给了一个大数组,程序运行超出时间限制,也就是说这种方法在某些情况下效率较低

当前算法的时间复杂度:O(N*K)

思路二

1、新建一个数组 nums1

在这里插入图片描述

2、将要轮转的部分整段移动过去

在这里插入图片描述

3、再把 nums1 的内容交还给 nums

在这里插入图片描述

这种算法的时间复杂度是 O(N),空间复杂度也是 O(N)

效率还是不够高,并且当给定的数组很大时,空间有可能不够用

思路三

流程

nums:1, 2, 3, 4, 5, 6, 7
k = 3

1、后 k 个逆置:1, 2, 3, 4, 7, 6, 5

2、前 n - k 个逆置:4, 3, 2, 1, 7, 6, 5

3、再整体逆置:5, 6, 7, 1, 2, 3, 4

逆置的实现

1、首尾交换

在这里插入图片描述

2、指针内移

在这里插入图片描述

3、再次交换,重复上面的过程,直至 left >= right

重点

在进行逆置时,一定要控制好元素的下标,即 Reverse (逆置函数)的实参

[1, 2, 3, 4, 5, 6, 7]
后k个逆置
5的下标为N-K,7的下标为N-1

[1, 2, 3, 4, 7, 6, 5]
前n-k个逆置
1的下标为0,4的下标为N-K-1

[4, 3, 2, 1, 7, 6, 5]
再整体逆置
4的下标为0,5的下标为N-1

完成
[5, 6, 7, 1, 2, 3, 4]

代码实现

void Reverse(int* nums, int left, int right)
{
	while (left < right)
	{
		int tmp = *(nums + left);
		*(nums + left) = *(nums + right);
		*(nums + right) = tmp;
		left++;
		right--;
	}
}

void rotate(int* nums, int numsSize, int k)
{
	if (k >= numsSize)
	{
		k %= numsSize;//每轮转numsSize次,相当于返回原状。如果不进行取余,N-K可能小于零,会导致数组越界
	}
	Reverse(nums, numsSize - k, numsSize - 1);
	Reverse(nums, 0, numsSize - 1 - k);
	Reverse(nums, 0, numsSize - 1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值