LeetCode 189. 轮转数组

导读:本篇文章讲解 LeetCode 189. 轮转数组,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

🌟 前言

Wassup guys!我是Edison 😎

今天是 LeetCode 上的 leetcode 189. 轮转数组

Let’s get it!

在这里插入图片描述



1. 题目分析

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

示例 1:
在这里插入图片描述

示例 2:
在这里插入图片描述

2. 题目图解

🍑 思路一:右旋 k 次,依次移动一个

假设我们要把数组 [1,2,3,4,5,6,7],向右旋转 3
在这里插入图片描述
1 步,定义一个变量 tmp 用于存放数组的最后一个元素 7

2 步,把数组前 n-1 个值往后挪;

3 步,把 tmp 的值放入空出来的第一个位置中;
在这里插入图片描述
这就完成了一次右旋,那么我们在向右旋转 k 次,就得到了最后的结果。

此方法时间复杂度为

O

(

N

K

)

O(N*K)

O(NK);空间复杂度为

O

(

1

)

O(1)

O(1)
 
K % N 等于 N-1 时,最坏,因为此时时间复杂度为

O

(

N

2

)

O(N^2)

O(N2)

🍑 思路二:额外开数组

这种方法是以 空间换时间 的做法。

很简单,再开辟一个数组,把后 k 个元素放到新数组 前面,再把前 n-k个放到新数组 后面。(n 为数组中的元素个数)。
在这里插入图片描述

此方法时间复杂度为

O

(

N

)

O(N)

O(N),空间复杂度为

O

(

N

)

O(N)

O(N)

🍑 思路三:三趟逆置

这种方法非常的 绝!,我们可以通过 三趟逆置 来解决,还是下面这个数组👇
在这里插入图片描述

1 趟,对数组的前 n – k 个逆置,如图所示👇
在这里插入图片描述

2 趟,对数组的后 k 个逆置,如图所示👇
在这里插入图片描述

3 趟,再把数组 整体逆置,如图所示👇
在这里插入图片描述

此方法时间复杂度为

O

(

N

)

O(N)

O(N),空间复杂度为

O

(

1

)

O(1)

O(1)

3. 算法设计

我们可以写一个 逆置 函数 reverse 来实现主要部分

📝 代码实现

void reverse(int* nums, int left, int right) {
	while (left < right) {
		int tmp = nums[left];
		nums[left] = nums[right];
		nums[right] = tmp;
		++left;
		--right;
	}
}

4. 代码实现

我们使用逆置函数 reverse 进行传参的时候要注意:数组的下标是从 0 开始的,比如:前 10 个元素是 09

因为第 1 趟要对前 n – k 逆置,此时 n = 7k = 3,那么就是要对前 4 个逆置,但是数组的下标是从 0 开始的,也就是说前 4 个元素的下标是 03,如图所示👇
在这里插入图片描述

2 趟,对数组的后 k 个逆置,也就是后 3 个元素逆置,也就是从下标 46 开始逆置,如图所示👇
在这里插入图片描述

3 趟,把整个数组逆置,如图所示👇
在这里插入图片描述
但是我们还要注意一个问题,如果 k 超过了数组元素的个数,怎么办呢?

比如:数组是 [ 1 2 3 4 5 ]k = 6 的时候,此时数组元素个数为 5,而要求向右旋转 6 个位置,如果按照上面分析的情况,第一趟对前 n – k 逆置,也就是 5 – 6 个逆置,难道对前 -1 个逆置吗?
在这里插入图片描述

我们先来看一下把数组向右轮转 6 个位置会怎么样,如图所示👇
在这里插入图片描述

咦!你会发现最后结果不就是 向右轮转 1 个位置 了吗?

此时我们要记住这道题的核心叫 轮转数组,也就是当轮转的次数超过数组长度的时候,又是新的一轮了!

所以我们可以先对 k 取余,然后再次旋转;比如数组长度为 8,我要向右轮转 10 次,其实就是向右轮转了 2 次,那么 10 % 2 的结果补就是 2 吗?

所以,如果 k 大于数组长度,故首先对 k 取余,然后再次旋转,这不会影响最终结果!

📝 接口代码

void reverse(int* nums, int left, int right) {
	while (left < right) {
		int tmp = nums[left];
		nums[left] = nums[right];
		nums[right] = tmp;
		++left;
		--right;
	}
}

void rotate(int* nums, int numsSize, int k) {
    k %= numsSize; // 如果k大于数组长度,先对k取余
	reverse(nums, 0, numsSize - k - 1);
	reverse(nums, numsSize - k, numsSize - 1);
	reverse(nums, 0, numsSize - 1);
}

🌟 提交结果
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80888.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!