Rotating array algorithm

1, Title

Given an array, move the elements in the array to the right k k k locations, where k k k is a nonnegative number.

Advanced:
Think of as many solutions as possible. There are at least three different ways to solve this problem.
You can use space complexity as O ( 1 ) O(1) Of O(1) In situ Does the algorithm solve this problem?

Example 1:

Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
Rotate one step to the right: [7,1,2,3,4,5,6]
Rotate 2 steps to the right: [6,7,1,2,3,4,5]
Rotate 3 steps to the right: [5,6,7,1,2,3,4] Example 2: Input: num = [- 1, - 100,3,99], k = 2
Output: [3,99, - 1, - 100]
Explanation:
Rotate 1 step to the right: [99, - 1, - 100,3]
Rotate 2 steps to the right: [3,99, - 1, - 100]

Tips:

1 < = n u m s . l e n g t h < = 2 ∗ 104 1 <= nums.length <= 2 * 104 1<=nums.length<=2∗104
− 231 < = n u m s [ i ] < = 231 − 1 -231 <= nums[i] <= 231 - 1 −231<=nums[i]<=231−1
0 < = k < = 105 0 <= k <= 105 0<=k<=105

2, Ideas and codes

1. Use temporary array

You can use a temporary array. First store the value of the original array in a temporary array, and then reassign the value of the temporary array to the original array. When reassigning, ensure that each element moves back k k k-bit. If it exceeds the length of the array, it starts from scratch, so it can be used here ( i + k ) (i + k) (i+k) % l e n g t h length length to calculate the index of the reassigned element.

code:

    public void rotate(int nums[], int k) {
        int length = nums.length;
        int temp[] = new int[length];
        //Put the original array value into a temporary array,
        for (int i = 0; i < length; i++) {
            temp[i] = nums[i];
        }
        //Then put the value of the temporary array back into the original array and move k bits to the right
        for (int i = 0; i < length; i++) {
            nums[(i + k) % length] = temp[i];
        }
    }

2. Multiple inversion

First invert all arrays, k before inverting, and finally invert the rest.

code:

    public void rotate(int[] nums, int k) {
        int length = nums.length;
        k %= length;
        reverse(nums, 0, length - 1);//Invert all elements first
        reverse(nums, 0, k - 1);//Invert the first k elements
        reverse(nums, k, length - 1);//Then reverse the rest
    }

    //Exchange the elements in the array from [start, end] in pairs, that is, reverse
    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start++] = nums[end];
            nums[end--] = temp;
        }
    }

In fact, under adjustment, you can first reverse the front, then reverse the k behind, and finally reverse all. The principle is the same

code:

    public void rotate(int[] nums, int k) {
        int length = nums.length;
        k %= length;
        reverse(nums, 0, length - k - 1);//Reverse the previous one first
        reverse(nums, length - k, length - 1);//Then reverse the last k
        reverse(nums, 0, length - 1);//Finally, all elements are reversed
    }

    //Exchange the elements in the array from [start, end] in pairs, that is, reverse
    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start++] = nums[end];
            nums[end--] = temp;
        }
    }

3. Circular rotation

Like Joseph's ring, it is easy to understand that the array is regarded as a ring, and each moves back k bits



be careful:
But there's a pit here, if ( i + k ) (i + k) (i+k) % l e n g t h = 0 length=0 length=0, that is, the array length is k k Multiple of k, this will rotate in place, as shown in the figure below

For this problem, we can use an array v i s i t e d visited visited indicates whether this element has been accessed. If it has been accessed, start from the next one to prevent it from rotating in place.

code:

    public static void rotate(int[] nums, int k) {
        int hold = nums[0];
        int index = 0;
        int length = nums.length;
        boolean[] visited = new boolean[length];
        for (int i = 0; i < length; i++) {
            index = (index + k) % length;
            if (visited[index]) {
                //If you have visited and visited again, you will turn around in place,
                //We can no longer access the current element. Let's start with its next element
                index = (index + 1) % length;
                hold = nums[index];
                i--;
            } else {
                //Save the current value in the next location. Before saving, save the current value in the next location
                //Record the value
                visited[index] = true;
                int temp = nums[index];
                nums[index] = hold;
                hold = temp;
            }
        }
    }

Reference article: https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2skh7/

Tags: Algorithm data structure leetcode

Posted on Fri, 15 Oct 2021 22:55:46 -0400 by xtrafile