leetcode-master/problems/0189.旋转数组.md

143 lines
4.4 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<p align="center">
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
</p>
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
# 189. 旋转数组
给定一个数组将数组中的元素向右移动 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]。
# 思路
这道题目在字符串里其实很常见,我把字符串反转相关的题目列一下:
* [字符串力扣541.反转字符串II](https://mp.weixin.qq.com/s/pzXt6PQ029y7bJ9YZB2mVQ)
* [字符串力扣151.翻转字符串里的单词](https://mp.weixin.qq.com/s/4j6vPFHkFAXnQhmSkq2X9g)
* [字符串剑指Offer58-II.左旋转字符串](https://mp.weixin.qq.com/s/Px_L-RfT2b_jXKcNmccPsw)
本题其实和[字符串剑指Offer58-II.左旋转字符串](https://mp.weixin.qq.com/s/Px_L-RfT2b_jXKcNmccPsw)就非常像了剑指offer上左旋转本题是右旋转。
注意题目要求是**要求使用空间复杂度为 O(1) 的 原地 算法**
那么我来提供一种旋转的方式哈。
在[字符串剑指Offer58-II.左旋转字符串](https://mp.weixin.qq.com/s/Px_L-RfT2b_jXKcNmccPsw)中,我们提到,如下步骤就可以坐旋转字符串:
1. 反转区间为前n的子串
2. 反转区间为n到末尾的子串
3. 反转整个字符串
本题是右旋转,其实就是反转的顺序改动一下,优先反转整个字符串,步骤如下:
1. 反转整个字符串
2. 反转区间为前k的子串
3. 反转区间为k到末尾的子串
**需要注意的是本题还有一个小陷阱题目输入中如果k大于nums.size了应该怎么办**
举个例子,比较容易想,
例如1,2,3,4,5,6,7 如果右移动15次的话是 7 1 2 3 4 5 6 。
所以其实就是右移 k % nums.size() 次15 % 7 = 1
C++代码如下:
```CPP
class Solution {
public:
void rotate(vector<int>& nums, int k) {
k = k % nums.size();
reverse(nums.begin(), nums.end());
reverse(nums.begin(), nums.begin() + k);
reverse(nums.begin() + k, nums.end());
}
};
```
# 其他语言版本
## Java
```java
class Solution {
private void reverse(int[] nums, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
}
public void rotate(int[] nums, int k) {
int n = nums.length;
k %= n;
reverse(nums, 0, n - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, n - 1);
}
}
```
## Python
```python
class Solution:
def rotate(self, A: List[int], k: int) -> None:
def reverse(i, j):
while i < j:
A[i], A[j] = A[j], A[i]
i += 1
j -= 1
n = len(A)
k %= n
reverse(0, n - 1)
reverse(0, k - 1)
reverse(k, n - 1)
```
## Go
```go
```
## JavaScript
```js
```
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
* B站视频[代码随想录](https://space.bilibili.com/525438321)
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码.jpg width=450> </img></div>