时间:2022-10-18 11:53:58 | 栏目:C代码 | 点击:次
给你一个数组,将数组中的元素向右轮转 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)
(5,6,7,4,3,2,1)
(5,6,7,1,2,3,4)
设置两个指针变量分别指向头部和尾部。当 begin<end 时,交换两个位置上的值。绿色的数字为交换的位置。
此处不赘述、同上面两个步骤的思路。这样就完成了对数组的轮转。
假如需要轮转的个数k大于数组numsSize的长度呢?
假如k为10,那么本题的结果是什么呢?
假如右旋10个数,那么先旋7个后将又回到了原来的样子。 然后再旋3个的话那么将和本题的旋3个一模一样。
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; }