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

相关文章
相关标签/搜索