LeetCode189.轮转数组

简介: LeetCode189.轮转数组

目录


189. 轮转数组

题目描述

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

你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

实例

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;
}
相关文章
|
2月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
41 0
|
4月前
|
算法
LeetCode第53题最大子数组和
LeetCode第53题"最大子数组和"的解题方法,利用动态规划思想,通过一次遍历数组,维护到当前元素为止的最大子数组和,有效避免了复杂度更高的暴力解法。
LeetCode第53题最大子数组和
LeetCode------找到所有数组中消失的数字(6)【数组】
这篇文章介绍了LeetCode上的"找到所有数组中消失的数字"问题,提供了一种解法,通过两次遍历来找出所有未在数组中出现的数字:第一次遍历将数组中的每个数字对应位置的值增加数组长度,第二次遍历找出所有未被增加的数字,即缺失的数字。
|
2月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
21 4
|
2月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
20 0
Leetcode第三十三题(搜索旋转排序数组)
|
2月前
|
算法 C++
Leetcode第53题(最大子数组和)
这篇文章介绍了LeetCode第53题“最大子数组和”的动态规划解法,提供了详细的状态转移方程和C++代码实现,并讨论了其他算法如贪心、分治、改进动态规划和分块累计法。
69 0
|
2月前
|
C++
【LeetCode 12】349.两个数组的交集
【LeetCode 12】349.两个数组的交集
18 0
|
4月前
|
算法
LeetCode第81题搜索旋转排序数组 II
文章讲解了LeetCode第81题"搜索旋转排序数组 II"的解法,通过二分查找算法并加入去重逻辑来解决在旋转且含有重复元素的数组中搜索特定值的问题。
LeetCode第81题搜索旋转排序数组 II
|
4月前
|
算法 索引
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
这篇文章介绍了LeetCode第34题"在排序数组中查找元素的第一个和最后一个位置"的解题方法,通过使用双指针法从数组两端向中间同时查找目标值,有效地找到了目标值的首次和最后一次出现的索引位置。
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
|
4月前
|
算法
LeetCode第33题搜索旋转排序数组
这篇文章介绍了LeetCode第33题"搜索旋转排序数组"的解题方法,通过使用二分查找法并根据数组的有序性质调整搜索范围,实现了时间复杂度为O(log n)的高效搜索算法。
LeetCode第33题搜索旋转排序数组