标签:
1、题目名称
Rotate Array(平移数组)
2、题目地址
https://leetcode.com/problems/rotate-array/
3、题目内容
英文:Rotate an array of n elements to the right by k steps.
中文:将一个长度为n的数组,向右平移k个单位
4、解题方法1
一个比较易于理解的方法是新开辟一个与原数组等长的数组,循环考察原数组的元素,将它们放到新数组中平移后的位置上,最后再将新数组上的元素赋回原数组。
一段可以AC的Java代码:
/** * 功能说明:LeetCode 189 - Rotate Array * 开发人员:Tsybius2014 * 开发时间:2015年8月9日 */ public class Solution { /** * 数组平移 * @param nums 数组 * @param k 平移距离 */ public void rotate(int[] nums, int k) { int[] tempArray = new int[nums.length]; k %= nums.length; //平移后的结果赋值到新数组 for (int i = 0; i < nums.length; i++) { int j = (i - k) % nums.length; if (j < 0) { j += nums.length; } tempArray[i] = nums[j]; } //将结果赋值回原数组 for (int i = 0; i < nums.length; i++) { nums[i] = tempArray[i]; } } }
这个做法的缺点就是需要申请一个与传入数组等长的数组,当传入数组长度较长时,新申请的数组长度也很大。因此可以考虑一个不新申请数组的做法。
5、解题方法2
先考虑数组nums的长度与k互质的情况。假设nums是一个长度为7的数组,k的值是3,那么只需要6次交换就可以完成数组的移位了。各位置元素交换的次序见下图:
每次交换,都把首个元素交换到它最终会出现的位置上,而每次交换后数组的首个元素,它最后会出现的位置都距上一个元素交换到的位置向右相差k(如果超过数组长度则从数组首元素重新计数)。
再考虑nums的长度不与k互质的情况,这个时候就需要求出nums的长度与k的最大公约数g,并将原数组分为g组,每组中的元素个数与k是互质的,分组进行上面的替换。
一段实现该算法的Java代码如下:
/** * 功能说明:LeetCode 189 - Rotate Array * 开发人员:Tsybius2014 * 开发时间:2015年8月9日 */ public class Solution { /** * 数组平移 * @param nums 数组 * @param k 平移距离 */ public void rotate(int[] nums, int k) { if (k == nums.length) { return; } if (k > nums.length) { k %= nums.length; } int temp; int loops = gcd(nums.length, k); for (int i = 0; i < loops; i++) { for (int j = 1; j < nums.length / loops; j++) { temp = nums[i]; nums[i] = nums[(i + k * j) % nums.length]; nums[(i + k * j) % nums.length] = temp; } } } /** * 辗转相除法求最大公约数 * @param a 正整数a * @param b 正整数b * @return 正整数a和b的最大公约数 */ public int gcd(int a, int b) { if (a == 0) { return b; } while (b != 0) { if (a > b) { a = a - b; } else { b = b - a; } } return a; } }
END
标签:
原文地址:http://my.oschina.net/Tsybius2014/blog/489726