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++
#include <bits/stdc++.h>
using namespace std;
int merge( int arr[], int temp[], int left,
int mid, int right)
{
int i, j, k;
int inv_count = 0;
i = left;
j = mid;
k = left;
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
temp[k++] = arr[i++];
else
{
temp[k++] = arr[j++];
inv_count = inv_count + (mid - i);
}
}
while (i <= mid - 1)
temp[k++] = arr[i++];
while (j <= right)
temp[k++] = arr[j++];
for (i = left; i <= right; i++)
arr[i] = temp[i];
return inv_count;
}
int _mergeSort( int arr[], int temp[], int left,
int right)
{
int mid, inv_count = 0;
if (right > left)
{
mid = (right + left)/2;
inv_count = _mergeSort(arr, temp, left,
mid);
inv_count += _mergeSort(arr, temp, mid+1,
right);
inv_count += merge(arr, temp, left, mid+1,
right);
}
return inv_count;
}
int mergeSort( int arr[], int array_size)
{
int *temp = ( int *) malloc ( sizeof ( int )*array_size);
return _mergeSort(arr, temp, 0, array_size - 1);
}
bool possibleSortingBy3SizeSubarray( int arr[], int N)
{
int numberOfInversion = mergeSort(arr, N);
return (numberOfInversion % 2 == 0);
}
int main()
{
int arr[] = {1, 3, 4, 2};
int N = sizeof (arr) / sizeof ( int );
possibleSortingBy3SizeSubarray(arr, N)?
cout << "Yes\n" : cout << "No\n" ;
}
|
Java
import java.io.*;
class GFG
{
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;
int j = mid;
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++;
inv_count = inv_count + (mid-i);
}
}
while (i <= (mid- 1 ))
temp[k++] = arr[i++];
while (j <= right)
temp[k++] = arr[j++];
for ( int l = left; l <= right; l++)
arr[l] = temp[l];
return inv_count;
}
public static int _mergeSort( int [] arr, int left, int right)
{
int mid, inv_count = 0 ;
if (left < right)
{
mid = (left + right)/ 2 ;
inv_count = _mergeSort(arr, left, mid);
inv_count += _mergeSort(arr, mid+ 1 , right);
inv_count += merge(arr, left, mid+ 1 , right);
}
return inv_count;
}
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);
return (numberOfInversion % 2 == 0 );
}
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
def merge(arr, temp, left, mid, right):
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
inv_count = inv_count + (mid - i)
while i < = mid - 1 :
temp[k] = arr[i]
k, i = k + 1 , i + 1
while j < = right:
temp[k] = arr[j]
k, j = k + 1 , j + 1
for i in range (left, right + 1 ):
arr[i] = temp[i]
return inv_count
def _mergeSort(arr, temp, left, right):
inv_count = 0
if right > left:
mid = (right + left) / / 2
inv_count = _mergeSort(arr, temp, left, mid)
inv_count + = _mergeSort(arr, temp, mid + 1 , right)
inv_count + = merge(arr, temp, left, mid + 1 , right)
return inv_count
def mergeSort(arr, array_size):
temp = [ None ] * array_size
return _mergeSort(arr, temp, 0 , array_size - 1 )
def possibleSortingBy3SizeSubarray(arr, N):
numberOfInversion = mergeSort(arr, N)
return (numberOfInversion % 2 = = 0 )
if __name__ = = "__main__" :
arr = [ 1 , 3 , 4 , 2 ]
N = len (arr)
if possibleSortingBy3SizeSubarray(arr, N):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
class GFG
{
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;
int j = mid;
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++;
inv_count = inv_count + (mid-i);
}
}
while (i <= (mid-1))
temp[k++] = arr[i++];
while (j <= right)
temp[k++] = arr[j++];
for ( int l = left; l <= right; l++)
arr[l] = temp[l];
return inv_count;
}
public static int _mergeSort( int []arr, int left,
int right)
{
int mid, inv_count = 0;
if (left < right)
{
mid = (left + right)/2;
inv_count = _mergeSort(arr, left, mid);
inv_count += _mergeSort(arr, mid+1, right);
inv_count += merge(arr, left, mid+1, right);
}
return inv_count;
}
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);
return (numberOfInversion % 2 == 0);
}
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" );
}
}
|
Javascript
<script>
function merge(arr, left, mid, right) {
let temp = new Array(arr.length);
let inv_count = 0;
let i = left;
let j = mid;
let k = left;
while ((i <= mid - 1) && (j <= right)) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i];
i++;
}
else {
temp[k++] = arr[j];
j++;
inv_count = inv_count + (mid - i);
}
}
while (i <= (mid - 1))
temp[k++] = arr[i++];
while (j <= right)
temp[k++] = arr[j++];
for (let l = left; l <= right; l++)
arr[l] = temp[l];
return inv_count;
}
function _mergeSort(arr, left, right) {
let mid, inv_count = 0;
if (left < right) {
mid = Math.floor((left + right) / 2);
inv_count = _mergeSort(arr, left, mid);
inv_count += _mergeSort(arr, mid + 1, right);
inv_count += merge(arr, left, mid + 1, right);
}
return inv_count;
}
function mergeSort(arr, N) {
return _mergeSort(arr, 0, N - 1);
}
function possibleSortingBy3SizeSubarray(arr, N) {
let numberOfInversion = mergeSort(arr, N);
return (numberOfInversion % 2 == 0);
}
let arr = [1, 3, 4, 2];
let N = arr.length;
if (possibleSortingBy3SizeSubarray(arr, N))
document.write( "Yes" );
else
document.write( "No" );
</script>
|
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.