189. Rotate Array
题目大意
Given an integer array nums, rotate the array to the right by k steps, where k is non-negative.
中文释义
给定一个整数数组 nums
,将数组向右旋转 k
步,其中 k
是非负数。
Example
Example 1:
- Input:
nums = [1,2,3,4,5,6,7]
,k = 3
- Output:
[5,6,7,1,2,3,4]
- Explanation:
- rotate 1 steps to the right:
[7,1,2,3,4,5,6]
- rotate 2 steps to the right:
[6,7,1,2,3,4,5]
- rotate 3 steps to the right:
[5,6,7,1,2,3,4]
- rotate 1 steps to the right:
Example 2:
- Input:
nums = [-1,-100,3,99]
,k = 2
- Output:
[3,99,-1,-100]
- Explanation:
- rotate 1 steps to the right:
[99,-1,-100,3]
- rotate 2 steps to the right:
[3,99,-1,-100]
- rotate 1 steps to the right:
Constraints
1 <= nums.length <= 10^5
-2^31 <= nums[i] <= 2^31 - 1
0 <= k <= 10^5
解题思路
三次翻转实现数组旋转的原理基于翻转操作的性质,这种方法有效地利用了翻转的数学特性来达到旋转的目的。下面是详细的解释:
1. 整体翻转:
首先对整个数组进行翻转。这一步的作用是将数组的后半部分移至前面,前半部分移至后面,但这样还不足以实现旋转的效果,因为元素的内部顺序也被颠倒了。
2. 翻转前 k 个元素:
然后对数组的前 k 个元素进行翻转。由于第一步中整体翻转了数组,这 k 个元素实际上是旋转后应该在数组前端的元素,但它们的顺序是颠倒的。这一步翻转将它们恢复到正确的顺序。
3. 翻转剩余部分:
最后,对数组剩余部分进行翻转。这部分同样在第一步中被颠倒了顺序,通过这一步翻转,它们也恢复到正确的顺序。
算法描述
实现了将一个整数数组 nums
向右旋转 k
步的功能。算法的主要步骤如下:
-
处理旋转次数:
- 由于旋转数组长度的倍数相当于没有旋转,所以首先对
k
进行取模操作,以处理k
大于数组长度的情况。
- 由于旋转数组长度的倍数相当于没有旋转,所以首先对
-
整体反转数组:
- 使用
reverse
函数将整个数组反转。这是实现旋转的关键步骤之一,它将数组的末尾元素移至数组的开始。
- 使用
-
** 局部反转数组的前
k
个元素 **:- 再次使用
reverse
函数,但这次仅反转数组的前k
个元素。这个步骤将旋转后应在数组前面的元素放到正确的位置。
- 再次使用
-
局部反转数组剩余部分:
- 最后,反转剩余部分的数组(从索引
k
到数组末尾)。这个步骤将旋转后应在数组后面的元素放到正确的位置。
- 最后,反转剩余部分的数组(从索引
代码示例
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());
}
};