一、題目名稱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