189J. Rotate Array

观察一个例子就好了

/**
    1 2 3 4 5 6 7 k = 3
    5 6 7 1 2 3 4
*/

那么等于先反转数组,然后分别反转 0,k-1 和 k, end。 当然还可以更高级的 不停换位,比如 index:0 -> index:3, index:3 -> index: 6, index:6 -> (6 + k = 3)%7 = index:2;

class Solution {
    public void rotate(int[] nums, int k) {
        int realK = k%nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, realK - 1);
        reverse(nums, realK, nums.length - 1);
    }
    public void reverse(int[] nums, int start, int end) {
        while( start < end ) {
            swap(nums, start++, end--);
        }
    }
    public void swap(int[] nums, int i , int j ) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

错误的cyclic replacement. 这是因为,很可能数组会分成好几组。 比如 [1 2 3 4 5 6] k = 2, 调换的话 1 3 5 自成一组循环。 2 4 6 永远不会被调换。

class Solution {
    //这是错误的答案
    public void rotate(int[] nums, int k) {
        if(k == 0) return;
        int candidate = nums[0];
        int index = 0;
        for(int i = 0; i < nums.length; i++){
            int newIndex = (index + k ) % nums.length;
            int temp = nums[newIndex];
            nums[newIndex] = candidate;
            candidate = temp;
            index = newIndex;
        }
    }
}

好的答案: 这里用 do while 是因为需要先执行一步,再用 curIndex != i 判断。用 while 直接就无法开始。 我想这就是 do while 的一个意义所在。

class Solution {
    public void rotate(int[] nums, int k) {
        if(k == 0) return;
        int count = 0;
        for(int i = 0; count < nums.length; i++){
            int candidate = nums[i];
            int curIndex = i;
            do{
                int newIndex = (curIndex + k ) % nums.length;
                int temp = nums[newIndex];
                nums[newIndex] = candidate;
                candidate = temp;
                curIndex = newIndex;
                count++;
            }while(curIndex != i);
        }
    }
}

2023 用一个 buffer array 一次 AC

class Solution {
    public void rotate(int[] nums, int k) {
        if (nums.length == 0) return;
        int N = nums.length;
        k = k % N;
        if (k == 0) return;
        int[] buffer = new int[k];
        for (int i = N - 1; i >= 0; i--) {
            if (i + k >= N) {
                buffer[(i + k) % N] = nums[i];
            } else {
                nums[i + k] = nums[i];
            }
        }
        for (int i = 0; i < buffer.length; i++) {
            nums[i] = buffer[i];
        }
        return;
    }
}

Last updated

Was this helpful?