welcome to my blog
LeetCode Top Interview Questions 189. Rotate Array (Java版; Easy)
题目描述
Given an array, rotate the array to the right by k steps, where k is non-negative.
Example 1:
Input: [1,2,3,4,5,6,7] and 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]
Example 2:
Input: [-1,-100,3,99] and 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]
Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
Could you do it in-place with O(1) extra space?
第一次做; 环状替代法; 不如力扣题解写得简洁; 移动过程有点类似链表反转操作
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null || nums.length==0)
return;
int n = nums.length;
k = k%n;
int count = 0;
int start = 0;
for(; count<n; start++){
int i = start;
int cur = nums[i];
int index;
int next;
do{
index = (i + k) % n;
next = nums[index];
nums[index] = cur;
count++;
i = index;
cur = next;
}while(i!=start);
}
}
}
第一次做; 时间复杂度O(N), 空间复杂度O(1); 三次翻转, 具体见例子; 细节: 处理前先更新k, 令k=k%n
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null || k%nums.length==0)
return;
int n = nums.length;
k = k%n;
int left=0, right=n-1;
while(left<right){
swap(nums, left++, right--);
}
left=0;
right=k-1;
while(left<right){
swap(nums, left++, right--);
}
left=k;
right = n-1;
while(left<right){
swap(nums, left++, right--);
}
}
public void swap(int[] arr, int i, int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
第一次做; 时间复杂度O(k*N), 空间复杂度O(1); 暴力解法, 每次旋转一个位置, 核心:处理的是位置, 处理顺序[0,n-1], 别理解成处理某个元素; 两个变量pre, cur; 暴力方法虽然慢, 但是要掌握暴力的处理流程
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null || k%nums.length==0)
return;
int n = nums.length;
k = k%n;
int pre, cur;
for(int i=0; i<k; i++){
pre = nums[n-1];
for(int j=0; j<n; j++){
cur = nums[j];
nums[j] = pre;
pre = cur;
}
}
}
}
第一次做; 时间复杂度O(N), 空间复杂度O(N); 就像循环移位一样; 创建一个等长的数组arr,将nums[0]放在arr的索引k位置, 之后再放nums[1,n-1], arr的索引要取模, 防止越界; 细节: java是值传递, 函数内改变nums不会影响外面的nums; 摘自力扣题解:我们可以用一个额外的数组来将每个元素放到正确的位置上,也就是原本数组里下标为 i 的我们把它放到 (i+k)%数组长度 的位置, 然后把新的数组拷贝到原数组中。
class Solution {
public void rotate(int[] nums, int k) {
if(nums==null || k%nums.length==0)
return;
int n = nums.length;
k = k%n;
int[] arr = new int[n];
for(int i=0; i<n; i++){
arr[(i+k)%n] = nums[i];
}
for(int i=0; i<n; i++){
nums[i] = arr[i];
}
}
}
力扣题解; 环状替代法; 第一次使用do while循环结构