Rotate Int Array in Java

Rotate Int Array in Java

Overview

Given an array of integers arr[] of size N and an integer, the task is to rotate the array elements to the left by d positions.

Array Rotation One By One

Solution Synopsis

At each iteration, shift the elements by one position to the left circularly (i.e., first element becomes the last). Perform this operation d times to rotate the elements to the left by d position.

Example:

  • Let us take arr[] = [1, 2, 3, 4, 5, 6, 7], d = 2.
  • First Step: => Rotate to left by one position. => arr[] = {2, 3, 4, 5, 6, 7, 1}
  • Second Step: => Rotate again to left by one position => arr[] = {3, 4, 5, 6, 7, 1, 2}
  • Rotation is done by 2 times. So the array becomes arr[] = {3, 4, 5, 6, 7, 1, 2}

Steps to solve the array rotation problem.

  • Rotate the array to left by one position. For that do the following:
  • Store the first element of the array in a temporary variable.
  • Shift the rest of the elements in the original array by one place.
  • Update the last index of the array with the temporary variable.
  • Repeat the above steps for the number of left rotations required.

Time Complexity: O(N * d)

Auxiliary Space: O(1)

package com.nullshots.algorithm.array.rotation;

import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ArrayRotationOneByOne {

    private static final Logger LOGGER = LoggerFactory.getLogger(ArrayRotationOneByOne.class);

    public static void main(final String[] args) {
        final int arrayToBeRotated[] = {1, 2, 3, 4, 5, 6, 7};
        final int d = 2;
        final int n = arrayToBeRotated.length;
        rotate(arrayToBeRotated, d, n);
    }
    
    public static void rotate(final int[] arrayToBeRotated, final int d, final int n) {
        for (int i = 0; i < d; i++) {
            int firstIndexData = arrayToBeRotated[0];
            for (int j = 0; j < n - 1; j++) {
                arrayToBeRotated[j] = arrayToBeRotated[j + 1];
            }
            arrayToBeRotated[n - 1] = firstIndexData;
            LOGGER.info(Arrays.toString(arrayToBeRotated));
        }
    }
}

Solution Synopsis

Array Rotation using Auxiliary Array.

After rotating d positions to the left, the first d elements become the last d elements of the array

  • First store the elements from index d to N-1 into the temp array.
  • Then store the first d elements of the original array into the temp array.
  • Copy back the elements of the temp array into the original array

Example:

  • Suppose the give array is arr[] = [1, 2, 3, 4, 5, 6, 7], d = 2.

  • First Step: => Store the elements from 2nd index to the last. => temp[] = [3, 4, 5, 6, 7]

  • Second Step: => Now store the first 2 elements into the temp[] array. => temp[] = [3, 4, 5, 6, 7, 1, 2]

  • Third Steps: => Copy the elements of the temp[] array into the original array. => arr[] = temp[] So arr[] = [3, 4, 5, 6, 7, 1, 2]

Steps to solve the array rotation problem.

  • Follow the steps below to solve the given problem.
  • Initialize a temporary array(temp[n]) of length same as the original array
  • Initialize an integer(k) to keep a track of the current index
  • Store the elements from the position d to n-1 in the temporary array
  • Now, store 0 to d-1 elements of the original array in the temporary array
  • Lastly, copy back the temporary array to the original array

Time complexity: O(N) Auxiliary Space: O(N)

package com.nullshots.algorithm.array.rotation;

import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ArrayRotationUsingTempArray {

    private static final Logger LOGGER = LoggerFactory.getLogger(ArrayRotationUsingTempArray.class);

    public static void main(final String[] args) {
        final int arrayToBeRotated[] = {1, 2, 3, 4, 5, 6, 7};
        final int d = 2;
        final int n = arrayToBeRotated.length;
        rotate(arrayToBeRotated, d, n);
    }

    public static void rotate(final int[] arrayToBeRotated, final int d, final int n) {

        // Current Value: {0,0,0,0,0,0,0}
        int rotatedArray[] = new int[n];
        int currentIndex = 0;

        // Moving numbers from index D - N
        // After Iteration : {3,4,5,6,7,0,0}
        for (int i = d; i < n; currentIndex++, i++) {
            rotatedArray[currentIndex] = arrayToBeRotated[i];
            LOGGER.info(Arrays.toString(rotatedArray));
        }

        // Moving numbers from index 0 - D
        // After Iteration : {3,4,5,6,7,1,2}
        for (int i = 0; i < d; currentIndex++, i++) {
            rotatedArray[currentIndex] = arrayToBeRotated[i];
            LOGGER.info(Arrays.toString(rotatedArray));
        }

        LOGGER.info(Arrays.toString(rotatedArray));
    }
}

Solution Synopsis

Array Rotation Using Juggling :

Instead of moving one by one, divide the array into different sets where the number of sets is equal to the GCD of N and d (say X. So the elements which are X distance apart are part of a set) and rotate the elements within sets by 1 position to the left.

  • Calculate the GCD between the length and the distance to be moved.
  • The elements are only shifted within the sets.
  • We start with temp = arr[0] and keep moving arr[I+d] to arr[I] and finally store temp at the right place.

Example:

Let arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} and d = 3

  • First step: => First set is {1, 4, 7, 10}. => Rotate this set by one position to the left. => This set becomes {4, 7, 10, 1} => Array arr[] = {4, 2, 3, 7, 5, 6, 10, 8, 9, 1, 11, 12}

  • Second step: => Second set is {2, 5, 8, 11}. => Rotate this set by one position to the left. => This set becomes {5, 8, 11, 2} => Array arr[] = {4, 5, 3, 7, 8, 6, 10, 11, 9, 1, 2, 12}

  • Third step: => Third set is {3, 6, 9, 12}. => Rotate this set by one position to the left. => This set becomes {6, 9, 12, 3} => Array arr[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3}

Steps to solve the array rotation problem.

  • Perform d%n in order to keep the value of d within the range of the array where d is the number of times the array is rotated and N is the size of the array.
  • Calculate the GCD(N, d) to divide the array into sets.
  • Run a for loop from 0 to the value obtained from GCD.
  • Store the value of arr[i] in a temporary variable (the value of i denotes the set number).
  • Run a while loop to update the values according to the set.
  • After exiting the while loop assign the value of arr[j] as the value of the temporary variable (the value of j denotes the last element of the ith set).

Time complexity : O(N) Auxiliary Space : O(1)

package com.nullshots.algorithm.array.rotation;

import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ArrayRotationUsingJuggling {

    private static final Logger LOGGER = LoggerFactory.getLogger(ArrayRotationUsingJuggling.class);

    public static void main(final String[] args) {
        final int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
        final int d = 3;
        final int n = arr.length;
        rotate(arr, d, n);
    }

    public static void rotate(final int[] arr, int d, final int n) {
        // Special Case: When d >= n
        d = d % n;
        int gcd = getGreatestCommonDivisor(d, n);
        for (int i = 0; i < gcd; i++) {
            int temp = arr[i];
            int j = i;
            while (true) {
                int k = j + d;
                if (k >= n) k = k - n;
                if (k == i) break;
                arr[j] = arr[k];
                j = k;
                LOGGER.info(Arrays.toString(arr));
            }
            arr[j] = temp;
        }
        LOGGER.info(Arrays.toString(arr));
    }

    /** READ HOW TO CALCULATE GCD AND WHAT IS GCD. */
    private static int getGreatestCommonDivisor(final int a, final int b) {
        if (b == 0) return a;
        else return getGreatestCommonDivisor(b, a % b);
    }
}

Solution Synopsis

#Array Rotation Using Reversal

Instead of moving one by one, divide the array into different sets where the number of sets is equal to the GCD of N and d (say X. So the elements which are X distance apart are part of a set) and rotate the elements within sets by 1 position to the left.

  • Calculate the GCD between the length and the distance to be moved.
  • The elements are only shifted within the sets.
  • We start with temp = arr[0] and keep moving arr[I+d] to arr[I] and finally store temp at the right place.

Example:

  • If we observe closely, we can see that a group of array elements is changing its position. For example see the following array:
  • arr[] = {1, 2, 3, 4, 5, 6, 7} and d = 2. The rotated array is {3, 4, 5, 6, 7, 1, 2}
  • The group having the first two elements is moving to the end of the array. This is like reversing the array.
  • But the issue is that if we only reverse the array, it becomes {7, 6, 5, 4, 3, 2, 1}.
  • After rotation the elements in the chunks having the first 5 elements {7, 6, 5, 4, 3} and the last 2 elements {2, 1} should be in the actual order as of the initial array [i.e., {3, 4, 5, 6, 7} and {1, 2}]but here it gets reversed.
  • So if those blocks are reversed again we get the desired rotated array.

So the sequence of operations is:

  • Reverse the whole array
  • Then reverse the last ‘d’ elements and
  • Then reverse the first (N-d) elements.

As we are performing reverse operations it is also similar to the following sequence:

  • Reverse the first ‘d’ elements
  • Reverse last (N-d) elements
  • Reverse the whole array.

Steps to solve the array rotation problem.

  • Algorithm reverse(arr, start, end): mid = (start + end)/2 loop from i = start to mid: swap (arr[i], arr[end-(mid-i+1)])
  • Algorithm rotate(arr, d, N): reverse(arr, 1, d) ; reverse(arr, d + 1, N); reverse(arr, 1,N);

Time complexity : O(N) Auxiliary Space : O(1)

Example:

  • For example take the array arr[] = {1, 2, 3, 4, 5, 6, 7} and d = 2.

  • The rotated array will look like {3, 4, 5, 6, 7, 1, 2}

* 1st Step: Consider the array as a combination of two blocks. One containing the first two elements and the other containing the remaining elements as shown above.
 +---+---+        +---+---+---+---+---+
 | 1 | 2 |        | 3 | 4 | 5 | 6 | 7 |
 +---+---+        +---+---+---+---+---+
 FIRST BLOCK      SECOND BLOCK
 Considered 2 blocks
 
  • 2nd Step: Now reverse the first d elements. It becomes as shown in the image +—+—+ +—+—+—+—+—+ | 2 | 1 | | 3 | 4 | 5 | 6 | 7 | +—+—+ +—+—+—+—+—+ REVERSED FIRST BLOCK SECOND BLOCK Reverse the first K elements

  • 3rd Step: Now reverse the last (N-d) elements. It become as it is shown in the below image:

+—+—+ +—+—+—+—+—+ | 2 | 1 | | 7 | 6 | 5 | 4 | 3 | +—+—+ +—+—+—+—+—+ REVERSED FIRST BLOCK REVERSED SECOND BLOCK Reverse the last (N-K) elements

  • 4th Step: Now the array is the exact reversed form of how it should be if left shifted d times. So reverse the whole array and you will get the required rotated array.

+—+—+—+—+—+—+—+ | 3 | 4 | 5 | 6 | 7 | 1 | 2 | +—+—+—+—+—+—+—+ The total array is reversed

See that the array is now the same as the rotated array.

package com.nullshots.algorithm.array.rotation;

import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ArrayRotationUsingReversal {

    private static final Logger LOGGER = LoggerFactory.getLogger(ArrayRotationUsingReversal.class);

    public static void main(final String[] args) {
        final int arr[] = {1, 2, 3, 4, 5, 6, 7};
        final int d = 2;
        final int n = arr.length;
        rotate(arr, d, n);
    }

    public static void rotate(final int[] arr, int d, final int n) {
        // Special Case 1: When D = 0, NO ROTATION REQUIRED
        if (d == 0) return;

        // Special Case 2: When D >= N
        d = d % n;

        // Reverse : First part of sub-array from index 0 - (D - 1)
        reverse(arr, 0, d - 1);

        // Reverse : Second part of sub-array from index D - (N - 1)
        reverse(arr, d, n - 1);

        // Reverse : Whole Array
        reverse(arr, 0, n - 1);

        LOGGER.info(Arrays.toString(arr));
    }

    private static void reverse(final int[] arr, int startIndex, int lastIndex) {
        while (startIndex <= lastIndex) {
            int temp = arr[startIndex];
            arr[startIndex] = arr[lastIndex];
            arr[lastIndex] = temp;
            lastIndex--;
            startIndex++;
        }
    }
}

Conclusion

In this article we have learned different ways of integer array rotation.

comments powered by Disqus
About Me

Pratiyush Kumar Singh

Hello, I’m Pratiyush. A Content writter, Developer. Quam nihil enim maxime corporis cumque totam aliquid nam sint inventore optio modi …

Know More