LeetCode之反转数组
Question:
Rotate Array QuestionEditorial Solution My Submissions
Total Accepted: 97790
Total Submissions: 425073
Difficulty: Easy
Contributors: Admin
Rotate an array of n elements to the right by k steps.
For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].
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?。在O(1)的空间内完成,也就不能用一个辅助数组了。
题意:给你一个数组,然后n是数组的元素个数,k是步骤,然后把数组反转。
我一开始对数组反转不太理解,因为以前没有碰到过(高手请忽略)。我一开始以为是数组反转是不是把数组倒序输出就行了。比如1,2,3,4 ===>4,3,2,1 ;一些语言的提供的函数也确实是这样,比如Java的Collections类下的reverse函数就是用于反转的。详情请见:http://www.runoob.com/java/arrays-reverse.html。因此,在这里应该区别,反转不是倒序输出,虽然输出的形式可能是一样,但是反转后,数组的元素位置是会发生改变,虽然你使用倒序输出可能可以通过OJ。这里的k 个步骤,我不是很理解。如果你清楚,烦请告知下。那么看样例,这里的k=3,可以理解是把后面3个数组元素移动到前面去。就比如k = 4;那么输出应该是 [4,5,6,7,1,2,3]。
从图片中的个人测试样例,是这样的。
那么下面怎么解呢?先来看一种简单易懂的。
public class solution{
public void rotate(int[] nums, int k){
int temp;
int n = nums.length;
for(int step = 0; step < k; step++){
temp = nums[n - 1];
for(int i = n - 1; i > 0; i--){
//后面的值覆盖前面的值
nums[i] = nums[i-1];
}
//把最后面的值赋值给第一个元素。
nums[0] = temp;
}
}
}
上面的是Java的代码实现,比较容易理解,数组的变化如下:
[1,2,3,4,5,6,7] //未做反转的数组
[7,1,2,3,4,5,6] //step = 0时
[6,7,1,2,3,4,5] //step = 1时
[5,6,7,1,2,3,4] //step = 2时
可见,如此交换两个值,我们的确可以得到对应的结果。当这种解法面对数组大的时,超时了。因为每一个step,数组可能都需要做移动n-1位的赋值操作。数组的移动是很费时的。时间复杂度为O(step*n);
因此,我使用了下面两种做法。
Java 方案:
package rotateArray;
public class RotateArray {
public static void main(String[] args) {
// TODO Auto-generated method stub
int nums[] = {1,2,3,4,5,6,7};
int k = 3;
rotate(nums, k);
for(int i = 0; i < nums.length; i++){
System.out.print(nums[i]);
}
}
public static void rotate(int[] nums, int k){
//获取数组的长度
int len = nums.length;
k = k % len;
//如果只有一个元素
if(len == 1){
return ;
}
/*如果k是0,那么k要是是0要么是length,但是这两种情况都不需要
* 对数组做任何改变
*/
if(k == 0){
return ;
}
//反转K位之前的数组元素
reverse(nums, 0, len-k-1);
//反转K位之后的数组元素
reverse(nums, len-k, len-1);
//反转整个数组的元素
reverse(nums, 0, len-1);
}
public static void reverse(int[] nums, int i, int j){
int temp;
//对没有被操作的数组元素的最前面和最后面的进行交换达到反转效果
while(i < j && i>=0){
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
i++; //左边向右移动一位
j--; //右边向左边移动一位
}
}
}
虽然说不能用辅助数组,但是C++使用vector容器装一个数组也能过。思考到k跟k%n的关系,这道题就变得很容易了。
C++方案:
class Solution {
public:
void rotate(vector<int>& nums, int k) {
vector<int> t = nums;
for(int i = 0; i < nums.size(); i++){
nums[(i + k) % nums.size()] = t[i];
}
}
};