LeetCode:Rotate Array - 循環平移數組

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

相關文章
相關標籤/搜索