Minimum swaps to reach permuted array with at most 2 positions left swaps allowed | This funt merges two sorted arrays and returns inversion count in the arrays . ; i is index for left subarray ; j is index for right subarray ; k is index for resultant merged subarray ; Copy the remaining elements of left subarray ( if there are any ) to temp ; Copy the remaining elements of right subarray ( if there are any ) to temp ; Copy back the merged elements to original array ; An auxiliary recursive function that sorts the input array and returns the number of inversions in the array . ; Divide the array into two parts and call _mergeSortAndCountInv ( ) for each of the parts ; Inversion count will be sum of inversions in left - part , right - part and number of inversions in merging ; Merge the two parts ; This function sorts the input array and returns the number of inversions in the array ; method returns minimum number of swaps to reach permuted array 'arr ; loop over all elements to check Invalid permutation condition ; if an element is at distance more than 2 from its actual position then it is not possible to reach permuted array just by swapping with 2 positions left elements so returning - 1 ; If permuted array is not Invalid , then number of Inversion in array will be our final answer ; Driver code to test above methods ; change below example
def merge ( arr , temp , left , mid , right ) : NEW_LINE INDENT inv_count = 0 NEW_LINE DEDENT i = left NEW_LINE j = mid NEW_LINE k = left NEW_LINE INDENT while ( i <= mid - 1 ) and ( j <= right ) : NEW_LINE INDENT if arr [ i ] <= arr [ j ] : NEW_LINE INDENT temp [ k ] = arr [ i ] NEW_LINE k , i = k + 1 , i + 1 NEW_LINE DEDENT else : NEW_LINE INDENT temp [ k ] = arr [ j ] NEW_LINE k , j = k + 1 , j + 1 NEW_LINE inv_count = inv_count + ( mid - i ) NEW_LINE DEDENT DEDENT while i <= mid - 1 : NEW_LINE INDENT temp [ k ] = arr [ i ] NEW_LINE k , i = k + 1 , i + 1 NEW_LINE DEDENT while j <= right : NEW_LINE INDENT temp [ k ] = arr [ j ] NEW_LINE k , j = k + 1 , j + 1 NEW_LINE DEDENT for i in range ( left , right + 1 ) : NEW_LINE INDENT arr [ i ] = temp [ i ] NEW_LINE DEDENT return inv_count NEW_LINE DEDENT def _mergeSort ( arr , temp , left , right ) : NEW_LINE INDENT inv_count = 0 NEW_LINE if right > left : NEW_LINE INDENT mid = ( right + left ) // 2 NEW_LINE inv_count = _mergeSort ( arr , temp , left , mid ) NEW_LINE inv_count += _mergeSort ( arr , temp , mid + 1 , right ) NEW_LINE inv_count += merge ( arr , temp , left , mid + 1 , right ) NEW_LINE DEDENT return inv_count NEW_LINE DEDENT def mergeSort ( arr , array_size ) : NEW_LINE INDENT temp = [ None ] * array_size NEW_LINE return _mergeSort ( arr , temp , 0 , array_size - 1 ) NEW_LINE DEDENT ' NEW_LINE def minSwapToReachArr ( arr , N ) : NEW_LINE INDENT for i in range ( 0 , N ) : NEW_LINE INDENT if ( arr [ i ] - 1 ) - i > 2 : NEW_LINE INDENT return - 1 NEW_LINE DEDENT DEDENT numOfInversion = mergeSort ( arr , N ) NEW_LINE return numOfInversion NEW_LINE DEDENT if __name__ == " _ _ main _ _ " : NEW_LINE INDENT arr = [ 1 , 2 , 5 , 3 , 4 ] NEW_LINE N = len ( arr ) NEW_LINE res = minSwapToReachArr ( arr , N ) NEW_LINE if res == - 1 : NEW_LINE INDENT print ( " Not ▁ Possible " ) NEW_LINE DEDENT else : NEW_LINE INDENT print ( res ) NEW_LINE DEDENT DEDENT