一、题目名称java
Rotate Array(循环平移数组)算法
二、题目地址数组
https://leetcode.com/problems/rotate-array/
oop
三、题目内容code
英文:Rotate an array of n elements to the right by k steps.
element
中文:将一个长度为n的数组,向右平移k个单位leetcode
四、解题方法1开发
一个比较易于理解的方法是新开辟一个与原数组等长的数组,循环考察原数组的元素,将它们放到新数组中平移后的位置上,最后再将新数组上的元素赋回原数组。get
一段能够AC的Java代码:
io
/** * 功能说明: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]; } } }
这个作法的缺点就是须要申请一个与传入数组等长的数组,当传入数组长度较长时,新申请的数组长度也很大。所以能够考虑一个不新申请数组的作法。
五、解题方法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