轮转数组(数据结构练习题1)

文章讲述了在C++中如何通过两种方法实现将整数数组向右轮转k位的问题,包括使用临时数组存储和直接数组内元素交换的方法,以及三次逆序操作的高效解法。
摘要由CSDN通过智能技术生成

广而告知: 博客写得好,Emoji要选好!!🎵 🎶 🔈 🔇 🔉 🔊 🔔 🔕 📣 📢
写博客是知识是巩固和温习,所以在这个信息爆炸的时代,每个人每天都要接收很多讯息,你的记忆是有限的,知识也是有限的,时间也是有限的,既然如此,那是时候磨亮我的五十米大刀了。 你很强,上天揽月你不行,你很强,下海捞鱼总行吧!

💀☠💩🤡👹👺👻👽👾🤖 -->渴望知识!!!
 

题目:给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: 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]

示例 2:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

提示:

  • 1 <= nums.length <= 105
  • -231 <= nums[i] <= 231 - 1
  • 0 <= k <= 105

那么如何实现这样的一道题:

1.解法1

在这里,从一开始考虑,我会定义多一个数组用于存放原来的数据,但是这个时间复杂度会大于0(1),但是也不妨作为代码的理解。

分析:

1)定义一个arr1[100],用于存储原来需要转换的数组。

2)以下这个代码是将需要跳转的后几位数numsize-K的数组存到原来的数组nums内

    for (int j = 0; j < k; j++)
    {
        nums[j] = arr1[j+numsize-k];
    }

3)将原数组nums内指向nums[k]之后的数据从arr1取出来,并存储到nums里面,从而完成数组内数据的交换。

 for (int n = 0; n < numsize - k; n++)
    {
        nums[n+k] = arr1[n];
    }

4)    lunzhuan(nums, 7, 4); 是将7个数中的后面4个数进行轮转交换位置。


#include <stdio.h>

void lunzhuan(int* nums, int numsize, int k)
{
	int arr1[100] = { 0 };
	for (int i = 0; i < numsize; i++)
	{
		arr1[i] = nums[i];
		printf("%d ", arr1[i]);
	}
	printf("\n");
	for (int j = 0; j < k; j++)
	{
		nums[j] = arr1[j+numsize-k];
	}
	for (int n = 0; n < numsize - k; n++)
	{
		nums[n+k] = arr1[n];
	}
	for (int k = 0; k<numsize; k++)
	{
		printf("%d ",nums[k]);
	}
	return 0;
}
int main()
{
	int size = 7;
	int nums[7] = {1,2,3,4,5,6,7};
	lunzhuan(nums, 7, 4);
	return 0;
}

大家可以看一下编译结果:

2.解法2

分析三次轮转是怎么轮转的:

1)首先原数组数据:

 2)第一次轮转,reserve(nums,0,numsSize-1),将所有的数据进行交换

3)第二次轮转,reserve(nums,0,k-1),再次轮转需要交换的0~K-1个数

4)第三次轮转,reserve(nums,k,numsSize-1),将数组内numsSize-k-1个数进行轮转交换。

上代码:



#include <stdio.h>
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) {
	if (k > numsSize)
	{
		k %= numsSize;    //求余的目的是什么? 就是为了将超过numsSize的数据,求余之后的余数作为需要逆转的元素个数
	}

	reverse(nums, 0, numsSize - 1);  //先将所有的数进行逆序 7,6,5,4,3,2,1
	reverse(nums, 0, k - 1);         //只对需要逆序的k个数进行逆序,6,7,5,4,3,2,1
	reverse(nums, k, numsSize - 1);  //只对numsSize-k 个数逆序:6,7,1,2,3,4,5
}

int main()
{
	int nums[7] = { 1,2,3,4,5,6,7 };
	for (int i = 0; i < 7; i++)
	{
		printf("%d ", nums[i]);
	}
	printf("\n");
	rotate(nums, 7, 2);
	for (int i = 0; i < 7; i++)
	{
		printf("%d ", nums[i]);
	}
	return 0;
}

大家可以看编译结果:

最后,请各位发财的金手指,帮忙点点赞和关注!

💁‍♂️💁‍♀️🙋🙋‍♂️🙋‍♀️🧏🧏‍♂️一赞三连🧏‍♀️🙇🙇‍♂️🙇‍♀️🤦🤦‍♂️🤦‍♀️🤷🤷‍♂️🤷‍♀️

💁‍♂️💁‍♀️🙋🙋‍♂️🙋‍♀️🧏🧏‍♂️一赞三连🧏‍♀️🙇🙇‍♂️🙇‍♀️🤦🤦‍♂️🤦‍♀️🤷🤷‍♂️🤷‍♀️

💁‍♂️💁‍♀️🙋🙋‍♂️🙋‍♀️🧏🧏‍♂️一赞三连🧏‍♀️🙇🙇‍♂️🙇‍♀️🤦🤦‍♂️🤦‍♀️🤷🤷‍♂️🤷‍♀️
 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值