# Sorting possible using size 3 subarray rotation

• Difficulty Level : Medium
• Last Updated : 08 Jul, 2022

Given an array of integer values which need to be sorted by only one operation – subarray rotation where subarray size should be 3. For example, If our array is (1 2 3 4) then we can reach to (1 4 2 3), (3 1 2 4) in one step. We need to tell whether it is possible to sort the complete array with this operation or not.

Examples :

```Input  : arr[] = [1, 3, 4, 2]
Output : Yes
Possible by below rotations,
[1, 3, 4, 2] -> [1, 4, 2, 3] ->
[1, 2, 3, 4]

Input  : arr[] = [1, 2, 4, 3]
Output : No
Not possible to sort above array by any 3
size subarray rotation.```

Suppose we have one subarray as [A[i] A[i+1] A[i+2]]. After one rotation, we get [A[i+2], A[i], A[i+1]]

If we observe inversions before and after rotation, we can see that parity of inversion is not changed i.e. if [A[i] A[i+1] A[i+2]] has even number of inversions [A[i+2] A[i] A[i+1]] will have even inversions. Same is true for odd inversions. Due to movement of A[i+2], inversions either increase by 2 or decrease by 2 or remain same i.e. their parity won’t change.

After observing above fact we can say that if initial array configuration has even number of inversion then it is possible to make them zero making array completely sorted otherwise not. We use merge sort based method for counting inversions. After getting the number of inversions, we can easily check parity of inversion and conclude whether it is possible to sort the array or not.

Implementation:

## C++

 `// C++ program to check whether we can sort``// given array using 3 size subarray rotation``// or not``#include ``using` `namespace` `std;` `/* This function merges two sorted arrays and``   ``returns inversion count in the arrays.*/``int` `merge(``int` `arr[], ``int` `temp[], ``int` `left,``                        ``int` `mid, ``int` `right)``{``    ``int` `i, j, k;``    ``int` `inv_count = 0;` `    ``i = left; ``/* i is index for left subarray*/``    ``j = mid;  ``/* j is index for right subarray*/``    ``k = left; ``/* k is index for resultant merged``                 ``subarray*/``    ``while` `((i <= mid - 1) && (j <= right))``    ``{``        ``if` `(arr[i] <= arr[j])``            ``temp[k++] = arr[i++];``        ``else``        ``{``            ``temp[k++] = arr[j++];` `            ``/* this is tricky -- see above``               ``explanation/diagram for merge()*/``            ``inv_count = inv_count + (mid - i);``        ``}``    ``}` `    ``/* Copy the remaining elements of left subarray``      ``(if there are any) to temp */``    ``while` `(i <= mid - 1)``        ``temp[k++] = arr[i++];` `    ``/* Copy the remaining elements of right subarray``       ``(if there are any) to temp*/``    ``while` `(j <= right)``       ``temp[k++] = arr[j++];` `    ``/* Copy back the merged elements to original``       ``array */``    ``for` `(i = left; i <= right; i++)``        ``arr[i] = temp[i];` `    ``return` `inv_count;``}` `/* An auxiliary recursive function that sorts``   ``the input array and returns the number of``   ``inversions in the array. */``int` `_mergeSort(``int` `arr[], ``int` `temp[], ``int` `left,``                                      ``int` `right)``{``    ``int` `mid, inv_count = 0;``    ``if` `(right > left)``    ``{``        ``/* Divide the array into two parts and``           ``call _mergeSortAndCountInv() for each``           ``of the parts */``        ``mid = (right + left)/2;` `        ``/* Inversion count will be sum of inversions``           ``in left-part, right-part and number of``           ``inversions in merging */``        ``inv_count  = _mergeSort(arr, temp, left,``                                           ``mid);``        ``inv_count += _mergeSort(arr, temp, mid+1,``                                          ``right);` `        ``/* Merge the two parts */``        ``inv_count += merge(arr, temp, left, mid+1,``                                            ``right);``    ``}``    ``return` `inv_count;``}`  `/* This function sorts the input array and returns the``   ``number of inversions in the array */``int` `mergeSort(``int` `arr[], ``int` `array_size)``{``    ``int` `*temp = (``int` `*)``malloc``(``sizeof``(``int``)*array_size);``    ``return` `_mergeSort(arr, temp, 0, array_size - 1);``}` `// method returns true is array can be sorted by 3``// size subarray rotation``bool` `possibleSortingBy3SizeSubarray(``int` `arr[], ``int` `N)``{``    ``int` `numberOfInversion = mergeSort(arr, N);` `    ``// if number of inversions are even then only``    ``// we can sort the array``    ``return` `(numberOfInversion % 2 == 0);``}` `//  Driver code to test above methods``int` `main()``{``    ``int` `arr[] = {1, 3, 4, 2};``    ``int` `N = ``sizeof``(arr) / ``sizeof``(``int``);` `    ``possibleSortingBy3SizeSubarray(arr, N)?``        ``cout << ``"Yes\n"` `: cout << ``"No\n"``;``}`

## Java

 `// Java program to check whether we can sort``// given array using 3 size subarray rotation``// or not``import` `java.io.*;` `class` `GFG``{``    ``/* This function merges two sorted arrays and``    ``returns inversion count in the arrays.*/``    ``public` `static` `int` `merge(``int``[] arr, ``int` `left, ``int` `mid, ``int` `right)``    ``{``        ``int``[] temp = ``new` `int``[arr.length];``        ``int` `inv_count = ``0``;``        ``int` `i = left; ``/* i is index for left subarray*/``        ``int` `j = mid; ``/* j is index for right subarray*/``        ``int` `k = left; ``/* k is index for resultant merged``                         ``subarray*/``        ` `        ``while``((i <= mid-``1``) && (j <= right))``        ``{``            ``if``(arr[i] <= arr[j])``            ``{``                ``temp[k++] = arr[i];``                ``i++;``            ``}``            ``else``            ``{``                ``temp[k++] = arr[j];``                ``j++;``                ` `                ``/* this is tricky -- see above``                ``explanation/diagram for merge()*/``                ``inv_count = inv_count + (mid-i);``            ``}``        ``}``        ` `        ``/* Copy the remaining elements of left subarray``        ``(if there are any) to temp */``        ``while``(i <= (mid-``1``))``            ``temp[k++] = arr[i++];``        ` `        ``/* Copy the remaining elements of right subarray``        ``(if there are any) to temp*/``        ``while``(j <= right)``            ``temp[k++] = arr[j++];``         ` `        ``/* Copy back the merged elements to original``        ``array */`   `        ``for` `(``int` `l = left; l <= right; l++)``            ``arr[l] = temp[l];`` ` `        ``return` `inv_count;``    ``}``    ` `    ``/* An auxiliary recursive function that sorts``    ``the input array and returns the number of``    ``inversions in the array. */``    ``public` `static` `int` `_mergeSort(``int``[] arr, ``int` `left, ``int` `right)``    ``{``       ` `       ``int` `mid, inv_count = ``0``;``       ``if``(left < right)``       ``{``           ` `            ``/* Divide the array into two parts and``            ``call _mergeSortAndCountInv() for each``            ``of the parts */``            ``mid = (left + right)/``2``;``           ` `            ``/* Inversion count will be sum of inversions``            ``in left-part, right-part and number of``            ``inversions in merging */``            ``inv_count = _mergeSort(arr, left, mid);``            ``inv_count += _mergeSort(arr, mid+``1``, right);``           ` `            ``inv_count += merge(arr, left, mid+``1``, right);``           ` `        ``}``       ``return` `inv_count;``       ` `   ``}``    ` `    ``/* This function sorts the input array and returns the``    ``number of inversions in the array */``    ``public` `static` `int` `mergeSort(``int``[] arr, ``int` `N)``    ``{``    ` `        ``return` `_mergeSort(arr, ``0``, N-``1``);``    ``}``    ` `    ``public` `static` `boolean` `possibleSortingBy3SizeSubarray(``int` `arr[], ``int` `N)``    ``{``        ``int` `numberOfInversion = mergeSort(arr, N);`` ` `        ``// if number of inversions are even then only``        ``// we can sort the array``        ``return` `(numberOfInversion % ``2` `== ``0``);``    ``}``    ` `    ``//  Driver code to test above methods``    ``public` `static` `void` `main (String[] args)``    ``{``        ` `        ``int` `arr[] = {``1``, ``3``, ``4``, ``2``};``        ``int` `N = arr.length;`` ` `        ``if``(possibleSortingBy3SizeSubarray(arr, N))``            ``System.out.println( ``"Yes"``);``        ``else``            ``System.out.println(``"No"``);``    ``}``}`

## Python3

 `# Python3 program to check whether we can sort``# given array using 3 size subarray rotation or not` `# This function merges two sorted arrays and``# returns inversion count in the arrays.``def` `merge(arr, temp, left, mid, right):``    ` `    ``# i is index for left subarray``    ``# j is index for right subarray``    ``# k is index for resultant merged subarray``    ``i, j, k, inv_count ``=` `left, mid, left, ``0``    ` `    ``while` `(i <``=` `mid ``-` `1``) ``and` `(j <``=` `right):``    ` `        ``if` `arr[i] <``=` `arr[j]:``            ``temp[k] ``=` `arr[i]``            ``k, i ``=` `k ``+` `1``, i ``+` `1``        ` `        ``else``:``            ``temp[k] ``=` `arr[j]``            ``k, j ``=` `k ``+` `1``, j ``+` `1` `            ``# This is tricky -- see above``            ``# explanation/diagram for merge()``            ``inv_count ``=` `inv_count ``+` `(mid ``-` `i)` `    ``# Copy the remaining elements of left``    ``# subarray (if there are any) to temp``    ``while` `i <``=` `mid ``-` `1``:``        ``temp[k] ``=` `arr[i]``        ``k, i ``=` `k ``+` `1``, i ``+` `1` `    ``# Copy the remaining elements of right``    ``# subarray (if there are any) to temp``    ``while` `j <``=` `right:``        ``temp[k] ``=` `arr[j]``        ``k, j ``=` `k ``+` `1``, j ``+` `1` `    ``# Copy back the merged elements``    ``# to original array``    ``for` `i ``in` `range``(left, right ``+` `1``):``        ``arr[i] ``=` `temp[i]` `    ``return` `inv_count` `# An auxiliary recursive function that``# sorts the input array and returns the``# number of inversions in the array.``def` `_mergeSort(arr, temp, left, right):` `    ``inv_count ``=` `0``    ``if` `right > left:``    ` `        ``# Divide the array into two parts``        ``# and call _mergeSortAndCountInv()``        ``# for each of the parts``        ``mid ``=` `(right ``+` `left) ``/``/` `2` `        ``# Inversion count will be sum of``        ``# inversions in left-part, right-part``        ``# and number of inversions in merging``        ``inv_count ``=` `_mergeSort(arr, temp, left, mid)``        ``inv_count ``+``=` `_mergeSort(arr, temp, mid ``+` `1``, right)` `        ``# Merge the two parts``        ``inv_count ``+``=` `merge(arr, temp, left, mid ``+` `1``, right)``    ` `    ``return` `inv_count` `# This function sorts the input array and``# returns the number of inversions in the array``def` `mergeSort(arr, array_size):` `    ``temp ``=` `[``None``] ``*` `array_size``    ``return` `_mergeSort(arr, temp, ``0``, array_size ``-` `1``)` `# method returns true is array can be``# sorted by 3 size subarray rotation``def` `possibleSortingBy3SizeSubarray(arr, N):` `    ``numberOfInversion ``=` `mergeSort(arr, N)` `    ``# if number of inversions are even``    ``# then only we can sort the array``    ``return` `(numberOfInversion ``%` `2` `=``=` `0``)` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:` `    ``arr ``=` `[``1``, ``3``, ``4``, ``2``]``    ``N ``=` `len``(arr)` `    ``if` `possibleSortingBy3SizeSubarray(arr, N):``        ``print``(``"Yes"``)``    ``else``:``        ``print``(``"No"``)` `# This code is contributed by Rituraj Jain`

## C#

 `// C# program to check whether we``// can sort given array using 3 size``// subarray rotation or not.``using` `System;` `class` `GFG``{``    ``/* This function merges two sorted arrays and``       ``returns inversion count in the arrays.*/``    ``public` `static` `int` `merge(``int` `[]arr, ``int` `left,``                             ``int` `mid, ``int` `right)``    ``{``        ``int` `[]temp = ``new` `int``[arr.Length];``        ``int` `inv_count = 0;``        ` `        ``/* i is index for left subarray*/``        ``int` `i = left;``        ` `        ``/* j is index for right subarray*/``        ``int` `j = mid; ``        ` `        ``/* k is index for resultant merged subarray*/``        ``int` `k = left;``        ` `        ``while``((i <= mid-1) && (j <= right))``        ``{``            ``if``(arr[i] <= arr[j])``            ``{``                ``temp[k++] = arr[i];``                ``i++;``            ``}``            ``else``            ``{``                ``temp[k++] = arr[j];``                ``j++;``                ` `                ``/* this is tricky -- see above``                ``explanation/diagram for merge()*/``                ``inv_count = inv_count + (mid-i);``            ``}``        ``}``        ` `        ``/* Copy the remaining elements of``           ``left subarray (if there are any)``           ``to temp */``        ``while``(i <= (mid-1))``            ``temp[k++] = arr[i++];``        ` `        ``/* Copy the remaining elements of``           ``right subarray (if there are any)``           ``to temp*/``        ``while``(j <= right)``            ``temp[k++] = arr[j++];``        ` `        ``/* Copy back the merged elements``           ``to original array */``        ``for` `(``int` `l = left; l <= right; l++)``            ``arr[l] = temp[l];` `        ``return` `inv_count;``    ``}``    ` `    ``/* An auxiliary recursive function that sorts``       ``the input array and returns the number of``       ``inversions in the array. */``    ``public` `static` `int` `_mergeSort(``int` `[]arr, ``int` `left,``                                           ``int` `right)``    ``{``      ``int` `mid, inv_count = 0;``      ``if``(left < right)``      ``{``            ``/* Divide the array into two parts and``               ``call _mergeSortAndCountInv() for each``               ``of the parts */``            ``mid = (left + right)/2;``            ` `            ``/* Inversion count will be sum of inversions``               ``in left-part, right-part and number of``               ``inversions in merging */``            ``inv_count = _mergeSort(arr, left, mid);``            ``inv_count += _mergeSort(arr, mid+1, right);``            ``inv_count += merge(arr, left, mid+1, right);``            ` `     ``}``    ``return` `inv_count;``        ` `}``    ` `    ``/* This function sorts the input array``       ``and returns the number of inversions``       ``in the array */``    ``public` `static` `int` `mergeSort(``int``[] arr, ``int` `N)``    ``{``        ``return` `_mergeSort(arr, 0, N-1);``    ``}``    ` `    ``public` `static` `bool` `possibleSortingBy3SizeSubarray(``int` `[]arr,``                                                          ``int` `N)``    ``{``        ``int` `numberOfInversion = mergeSort(arr, N);` `        ``// if number of inversions are even``        ``// then only we can sort the array``        ``return` `(numberOfInversion % 2 == 0);``    ``}``    ` `    ``// Driver code to test above methods``    ``public` `static` `void` `Main ()``    ``{``        ``int` `[]arr = {1, 3, 4, 2};``        ``int` `N = arr.Length;` `        ``if``(possibleSortingBy3SizeSubarray(arr, N))``            ``Console.Write( ``"Yes"``);``        ``else``            ``Console.Write(``"No"``);``    ``}``}` `// This code is contributed by nitin mittal.`

## Javascript

 ``

Output

`Yes`

Time Complexity : O(n Log n)

This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

My Personal Notes arrow_drop_up