题目

    给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

    进阶:

    尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
    你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

    示例 1:

    输入: nums = [1,2,3,4,5,6,7], k = 3
    输出: [5,6,7,1,2,3,4]
    解释:
    向右旋转 1 步: [7,1,2,3,4,5,6]
    向右旋转 2 步: [6,7,1,2,3,4,5]
    向右旋转 3 步: [5,6,7,1,2,3,4]

    示例 2:

    输入:nums = [-1,-100,3,99], k = 2
    输出:[3,99,-1,-100]
    解释:
    向右旋转 1 步: [99,-1,-100,3]
    向右旋转 2 步: [3,99,-1,-100]

    提示:

    1 <= nums.length <= 2 * 104
    -231 <= nums[i] <= 231 - 1
    0 <= k <= 105


    暴力解:用另一个数组来暂时存储,空间复杂度为O(n)

    1. public class Sollution {
    2. public void rotate(int[] nums, int k) {
    3. int n=nums.length;
    4. int[] ans=new int[n];
    5. for (int i=0;i<k;i++){
    6. ans[i]=nums[n-k+i];
    7. }
    8. for (int i=0;i<n-k;i++){
    9. ans[k+i]=nums[i];
    10. }
    11. for (int i=0;i<n;i++){
    12. nums[i]=ans[i];
    13. }
    14. return;
    15. }
    16. }

    上面这个写得比较傻逼还不怎么会Java

    public void rotate(int[] nums, int k) {
        int n = nums.length;
        int[] newArr = new int[n];
        for (int i = 0; i < n; ++i) {
            newArr[(i + k) % n] = nums[i];
        }
        System.arraycopy(newArr, 0, nums, 0, n);
    }
    

    环状替代:用代数在原来的数组里一个一个换,这样空间复杂度就是O(1)了

    class Solution {
        public void rotate(int[] nums, int k) {
            int n = nums.length;
            k = k % n;
            int count = gcd(k, n);
            for (int start = 0; start < count; ++start) {
                int current = start;
                int prev = nums[start];
                do {
                    int next = (current + k) % n;
                    int temp = nums[next];
                    nums[next] = prev;
                    prev = temp;
                    current = next;
                } while (start != current);
            }
        }
    
        public int gcd(int x, int y) {
            return y > 0 ? gcd(y, x % y) : x;
        }
    }
    

    数组翻转:

    操作 结果
    原始数组 1 2 3 4 5 6 7
    翻转所有元素 7 6 5 4 3 2 1
    翻转[[0, k mod n - 1]区间的元素 5 6 7 4 3 2 1
    翻转 [k mod n, n - 1]区间的元素 5 6 7 1 2 3 4
    class Solution {
        public void rotate(int[] nums, int k) {
            k %= nums.length;
            reverse(nums, 0, nums.length - 1);
            reverse(nums, 0, k - 1);
            reverse(nums, k, nums.length - 1);
        }
    
        public void reverse(int[] nums, int start, int end) { //数组翻转函数
            while (start < end) {
                int temp = nums[start];
                nums[start] = nums[end];
                nums[end] = temp;
                start += 1;
                end -= 1;
            }
        }
    }