《LeetCode之每日一题》:17. 旋转数组
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:17. 旋转数组相关的知识,希望对你有一定的参考价值。
题目链接: 旋转数组
有关题目
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
进阶:
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
你可以使用空间复杂度为 O(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:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 2 * 10^4
-2^31 <= nums[i] <= 2^31 - 1
0 <= k <= 10^5
题解
1、暴力法(超时)
void rotate(int* nums, int numsSize, int k){
//暴力求解法--旋转k次
while(k--)
{
int tmp = nums[numsSize - 1];
for (int i = numsSize - 2; i >= 0; i--)
{
nums[i + 1] = nums[i];
}
nums[0] = tmp;
}
}
2、以空间换时间–开辟额外空间
void rotate(int* nums, int numsSize, int k){
k %= numsSize;//我们只保证0~numsSize内的反转
int* tmp = (int*)calloc(numsSize,sizeof(int));
memcpy(tmp,nums + numsSize - k,sizeof(int) * k);
memcpy(tmp + k,nums,sizeof(int) * (numsSize - k));
memcpy(nums,tmp,numsSize * sizeof(int));
}
时间复杂度:O(N).涉及到拷贝次数
空间复杂度:O(N)多开辟了numsSize大小的空间
3、三次反转
思路:
①先反转前numsSize - k 个元素
②再反转后k个元素
③最后整体反转
以下面的数组为例
1,2,3,4,5,6,7--k = 3
前numsSize - k 个元素反转--> 4 3 2 1 5 6 7
后k 个元素反转-->4 3 2 1 7 6 5
整体反转--> 5 6 7 1 2 3 4
void Reverse(int* begin,int* end)
{
int* l = begin;
int* r = end;
while(l <= r)
{
int tmp = *l;
*l = *r;
*r = tmp;
l++;
r--;
}
return ;
}
void rotate(int* nums, int numsSize, int k){
k %= numsSize;//你不叫这个就会出现一定程度的错误
Reverse(nums,nums + numsSize - k - 1);
Reverse(nums + numsSize - k,nums + numsSize - 1);
Reverse(nums,nums+numsSize - 1);
return ;
}
时间复杂度:O(N)
空间复杂度:O(1)
以1,2,3,4,5,6,7--k = 4为例
多种方式进行反转
下面的反转都是按照先前numsSize - k 个元素
再后k 个元素
最后整体反转
①上式中
②函数实现:Reverse(nums,int l,int r){
while(l < r)
{
//创建临时变量
int tmp = nums[l];
nums[l++] = nums[r];
nums[r--] = tmp;
//加减运算
nums[l] = nums[l] + nums[r];
nums[r] = nums[l] - nums[r];
nums[l] = nums[
}
}
Reverse(nums,0,numsSize - k - 1)
Reverse(nums,numsSize - k,numsSize - 1)
Reverse(nums,0,numsSize - 1)
Reverse
以上是关于《LeetCode之每日一题》:17. 旋转数组的主要内容,如果未能解决你的问题,请参考以下文章
《LeetCode之每日一题》:268.寻找旋转数组中的最小值