myshuangwaiwai

LeetCode189——Rotate Array

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].

Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.

 


拿到题目第一印象就是每次右移一个位置,按次数k进行k次循环。

代码一:

 1 public class test1 {
 2     public static void rotate(int[] nums, int k) {
 3         for (int i = 0; i < k; i++)
 4             rotateOneStep(nums);
 5     }
 6 
 7     public static void rotateOneStep(int[] nums) {
 8         int tmp = nums[nums.length - 1];
 9         for (int i = nums.length - 1; i > 0; i--) {
10             nums[i] = nums[i - 1];
11         }
12         nums[0] = tmp;
13     }
14 
15     public static void main(String[] args) {
16         int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7 };
17         rotate(array, 3);
18         for(int i = 0; i < array.length;i++)
19             System.out.println(array[i]);
20     }
21 }

 

测试了下运行OK,但问题是效率不高,复杂度为O(k*n),提交上去显示Time Limit Exceeded。但是实现了空间复杂度是O(1)。

 

第二种方法就是扩容,在原数组后面复制一遍,之后截取。这里一个问题就是会额外占用许多空间。(另一个类似的方法是直接从第k个节点复制给新建数组)算法复杂度都为O(n)

代码二:

 1 public class test1 {
 2     public static void rotate(int[] nums, int k) {
 3         k = k % nums.length;
 4         int[] temp = new int[nums.length * 2];
 5         for (int i = 0; i < nums.length; i++) {
 6             temp[i] = nums[i];
 7             temp[i + nums.length] = nums[i];
 8         }
 9         int res = nums.length - k;
10         for (int i = 0; i < nums.length; i++) {
11             nums[i] = temp[res];
12             res++;
13         }
14     }
15 
16     public static void main(String[] args) {
17         int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7 };
18         rotate(array, 3);
19         for(int i = 0; i < array.length; i++ )
20             System.out.println(array[i]);
21     }
22 }

代码三:

 1 public class test1 {
 2     public static void rotate(int[] nums, int k) {
 3         int[] copyNums = new int[nums.length];
 4         for( int i = 0 ; i < nums.length ; i++ )
 5             copyNums[( i + k ) % nums.length] = nums[i];
 6         for(int i = 0; i < copyNums.length; i++ ){
 7             nums[i] = copyNums[i];
 8             System.out.println(nums[i]);
 9         }
10     }
11 
12     public static void main(String[] args) {
13         int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7 ,8};
14         rotate(array, 3);        
15     }
16 }

 

第三种思路更清晰,效率更高,跟字符串自由旋转一样的操作,采用三次翻转法。第一次翻转前n-k个,第二次翻转后k个,第三次翻转全部。该方法在n足够大时,效率最好。时间复杂度O(n),空间O(1)(需要判定k的值)

代码四:

 1 public class test1 {
 2     public static void rotate(int[] nums, int k) {
 3         k = k % nums.length;
 4         reverse(nums, 0, nums.length - k - 1);
 5         reverse(nums, nums.length - k, nums.length - 1);
 6         reverse(nums, 0, nums.length - 1);
 7     }
 8 
 9     private static int[] reverse(int[] array, int begin, int end) {
10         int temp;
11         for (; begin < end; begin++, end--) {
12             temp = array[begin];
13             array[begin] = array[end];
14             array[end] = temp;
15         }
16         return array;
17     }
18 
19     public static void main(String[] args) {
20         int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };
21         rotate(array, 3);
22         for (int i = 0; i < array.length; i++)
23             System.out.println(array[i]);
24     }
25 }

 

2015-04-16

posted on 2015-04-16 15:28  myshuangwaiwai  阅读(79)  评论(0编辑  收藏  举报