难度:简单java
题库地址:leetcode-cn.com/problems/ro…算法
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。数组
示例 1:bash
输入: [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:spa
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
复制代码
说明:.net
英文版的有答案:leetcode.com/problems/ro…3d
这里记录一下第4种方法的理解:Approach #4 Using Reverse [Accepted]code
假设对长度为 n 的数组,进行 k 次旋转。leetcode
首先要找到最终有效的次数,由于旋转的循环的,当对数组进行 n 次旋转时,至关于没有对数组进行操做,同时该方法必须先找到最终有效次数,不然无法对数组进行镜像操做。get
为何在不一样位置采用三次镜像操做就能实现数组的 k 次旋转,连同答案和本身的理解整理为以下:
先计算 的有效次数,由于旋转是循环进行的,像自行车链条同样,当元素旋转一整圈即:
时,全部元素回到了原来的位置,因此
次旋转的有效次数为
。
咱们将数组以 为边界拆分红两部分看待,前
个元素部分:
和 后
个元素部分
,为何以
为分界点呢?由于对数组进行
次旋转后,
和
将互换位置。 如数组:
,长度
,进行
次旋转,对应
,
,旋转结束后获得数组:
,
为了实现将 和
位置互换,这里采用将整个数组镜像的策略。 原元素:
镜像后:
对数组进行镜像操做后,虽然 和
位置互换,可是其内部元素也被镜像了,为了将
和
内部元素的顺序恢复,对
和
再分别进行一次镜像。
举例以下原数组: 镜像前:
,
镜像后:
,
对
和
分别进行一次镜像后获得的最终结果:
,
最终答案:
算法思想再精简一点以下:
Java实现:
class Solution {
public void rotate(int[] nums, int k) {
if (nums == null || nums.length < 2) {
return;
}
// 计算有效旋转次数
k %= nums.length;
// 对整个数组镜像,使 S2 和 S1 位置互换
reverse(nums, 0, nums.length - 1);
// 对 S2 镜像处理,使其内部元素顺序恢复
reverse(nums, 0, k - 1);
// 对 S1 镜像处理,使其内部元素顺序恢复
reverse(nums, k, nums.length - 1);
}
private void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[end];
nums[end] = nums[start];
nums[start] = temp;
start++;
end--;
}
}
}
复制代码