这篇文章主要给大家讲解轮转数组的问题,一个问题不局限于一种解法,希望你看了本文的解决方法以后可以举一反三自己编写,这样你的技术水平会有质的提高
题目描述
给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。OJ链接
实例
1.实例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.实例2
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
解题思路
为了使算法空间复杂度为O(1),原地旋转,所以不能额外创建数组。
以实例1为例子。使用三次逆转法,让数组旋转k次
- 先整体逆转 变为
(7,6,5,4,3,2,1)
- 逆转子数组[0, k - 1] 变为
(5,6,7,4,3,2,1)
- 逆转子数组[k, numsSize - 1] 变为
(5,6,7,1,2,3,4)
1. 先整体逆转
设置两个指针变量分别指向头部和尾部。当 begin<end 时,交换两个位置上的值。绿色的数字为交换的位置。
2.逆转子数组[0, k - 1]
3.逆转子数组[k, numsSize - 1]
此处不赘述、同上面两个步骤的思路。这样就完成了对数组的轮转。
易错点
假如需要轮转的个数k大于数组numsSize的长度呢?
假如k为10,那么本题的结果是什么呢?
假如右旋10个数,那么先旋7个后将又回到了原来的样子。 然后再旋3个的话那么将和本题的旋3个一模一样。
- 本题的精髓就是题目,叫做轮转数组。果然天道好轮回。轮转7次又回到了起点。轮转14次,21次…,只要七的倍数都回返回原地。
- 所以在题目中要加入是否为k的倍数的判断代码
if (k > numsSize)
{
k %= numsSize;
}
代码
此代码带主函数。LeetCode题目中是接口类型的不带主函数。因为要轮转三次。所以把while循环写成一个函数,方便复用。
LeetCode189. 轮转数组
#include<stdio.h>
void rotate1(int* begin, int* end)
{
while (begin < end)
{
int t = 0;
t = *begin;
*begin = *end;
*end = t;
++begin;
--end;
}
}
void rotate(int* nums, int numsSize, int k)
{
//假如右旋10个数,先旋7个后又回到了原来的样子。然后再旋3次的话和本题再旋3次一模一样。
if (k > numsSize)
{
k %= numsSize;
}
int* begin = nums;
int* end = nums + numsSize - 1;
rotate1(begin, end);
rotate1(begin, begin+k-1);
rotate1(begin + k, end);
}
int main()
{
int nums[] = { 1,2,3,4,5,6,7 };
int sz = sizeof(nums) / sizeof(nums[0]);
rotate(nums, sz, 3);
for (int i = 0; i < sz; i++)
{
printf("%d ", nums[i]);
}
return 0;
}
到此这篇关于C语言超详细讲解轮转数组的文章就介绍到这了,更多相关C语言 轮转数组内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!
本文标题为:C语言超详细讲解轮转数组
- C++ 数据结构超详细讲解顺序表 2023-03-25
- C语言手把手带你掌握带头双向循环链表 2023-04-03
- 详解C语言中sizeof如何在自定义函数中正常工作 2023-04-09
- C语言qsort()函数的使用方法详解 2023-04-26
- Easyx实现扫雷游戏 2023-02-06
- c++ const 成员函数,返回一个 const 指针.但是返回的指针是什么类型的 const? 2022-10-11
- C语言详解float类型在内存中的存储方式 2023-03-27
- Qt计时器使用方法详解 2023-05-30
- ubuntu下C/C++获取剩余内存 2023-09-18
- 我应该为我的项目使用相对包含路径,还是将包含目录放在包含路径上? 2022-10-30