《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.寻找旋转数组中的最小值

《LeetCode之每日一题》:126.旋转图像

《LeetCode之每日一题》:16.面试题 17.04. 消失的数字

leetcode 每日一题 48. 旋转图像

leetcode 每日一题 48. 旋转图像

《LeetCode之每日一题》:215.打乱数组