Largest permutation after at most k swaps

08 Jul, 2022
Given a permutation of first n natural numbers as array and an integer k. Print the lexicographically largest permutation after at most k swaps 
Examples: 
Input: arr[] = {4, 5, 2, 1, 3}
       k = 3
Output: 5 4 3 2 1
Swap 1st and 2nd elements: 5 4 2 1 3 
Swap 3rd and 5th elements: 5 4 3 1 2 
Swap 4th and 5th elements: 5 4 3 2 1 

Input: arr[] = {2, 1, 3}
       k = 1
Output: 3 1 2
Swap 1st and 3re elements: 3 1 2
Naive approach: The idea is to generate one by one permutation in lexicographically decreasing order. Compare every generated permutation with original array and count the number of swaps required to convert. If count is less than or equal to k, print this permutation. The problem of this approach is that it would be difficult to implement and will definitely time out for the large value of N.
Algorithm: 
To find the minimum swaps to convert one array to another read this article.Copy the original array and sort that array in decreasing order. So the sorted array is the largest permutation of the original array.Now generate all permutation in lexicographically decreasing order. Previous permutation is calculated using prev_permutation() function.Find the minimum steps required to convert the new array (permutation in decreasing order) to original array, if the count is less than or equal to k. Then print the array and break.
To find the minimum swaps to convert one array to another read this article.
Copy the original array and sort that array in decreasing order. So the sorted array is the largest permutation of the original array.
Now generate all permutation in lexicographically decreasing order. Previous permutation is calculated using prev_permutation() function.
Find the minimum steps required to convert the new array (permutation in decreasing order) to original array, if the count is less than or equal to k. Then print the array and break.
Implementation:
C++14
#include <bits/stdc++.h>using namespace std; // Function returns the minimum number// of swaps required to sort the array// This method is taken from below post// https:// www.geeksforgeeks.org/// minimum-number-swaps-required-sort-array/int minSwapsToSort(int arr[], int n){    // Create an array of pairs where first    // element is array element and second    // element is position of first element    pair<int, int> arrPos[n];    for (int i = 0; i < n; i++) {        arrPos[i].first = arr[i];        arrPos[i].second = i;    }     // Sort the array by array element    // values to get right position of    // every element as second    // element of pair.    sort(arrPos, arrPos + n);     // To keep track of visited elements.    // Initialize all elements as not    // visited or false.    vector<bool> vis(n, false);     // Initialize result    int ans = 0;     // Traverse array elements    for (int i = 0; i < n; i++) {        // Already swapped and corrected or        // already present at correct pos        if (vis[i] || arrPos[i].second == i)            continue;         // Find out the number of  node in        // this cycle and add in ans        int cycle_size = 0;        int j = i;        while (!vis[j]) {            vis[j] = 1;             // move to next node            j = arrPos[j].second;            cycle_size++;        }         // Update answer by adding current        // cycle.        ans += (cycle_size - 1);    }     // Return result    return ans;} // method returns minimum number of// swap to make array B same as array Aint minSwapToMakeArraySame(    int a[], int b[], int n){    // Map to store position of elements    // in array B we basically store    // element to index mapping.    map<int, int> mp;    for (int i = 0; i < n; i++)        mp[b[i]] = i;     // now we're storing position of array    // A elements in array B.    for (int i = 0; i < n; i++)        b[i] = mp[a[i]];     /* We can uncomment this section to      print modified b array    for (int i = 0; i < N; i++)        cout << b[i] << " ";    cout << endl; */     // Returning minimum swap for sorting    // in modified array B as final answer    return minSwapsToSort(b, n);} // Function to calculate largest// permutation after atmost K swapsvoid KswapPermutation(    int arr[], int n, int k){    int a[n];     // copy the array    for (int i = 0; i < n; i++)        a[i] = arr[i];     // Sort the array in descending order    sort(arr, arr + n, greater<int>());     // generate permutation in lexicographically    // decreasing order.    do {        // copy the array        int a1[n], b1[n];        for (int i = 0; i < n; i++) {            a1[i] = arr[i];            b1[i] = a[i];        }         // Check if it can be made same in k steps        if (            minSwapToMakeArraySame(                a1, b1, n)            <= k) {            // Print the array            for (int i = 0; i < n; i++)                cout << arr[i] << " ";            break;        }         // move to previous permutation    } while (prev_permutation(arr, arr + n));} int main(){    int arr[] = { 4, 5, 2, 1, 3 };    int n = sizeof(arr) / sizeof(arr[0]);    int k = 3;     cout << "Largest permutation after "         << k << " swaps:\n";     KswapPermutation(arr, n, k);    return 0;}
Largest permutation after 3 swaps:
5 4 3 2 1 
Complexity Analysis: 
Time Complexity: O(N!). To generate all permutation O(N!) time complexity is required.
Space Complexity: O(n). to store the new array O(n) space is required.
Another approach worth considering :  
This problem can be considered as an instance of a “controlled” selection sort . By controlled , we mean that we are not performing the selection sort operation on the entire array. Instead, we are constructing ourselves to only the total number of swaps K that we are allowed to perform. 
So in the following approach , all we need to do is simply let the selection sort go on for k times , not more than that . Also we need to check if the position of the maximum number we’re about to swap with the current position i is equal to the number already present in that position , and we need to jump over this particular situation , lest we should waste our limited number of swaps . 
Implementation:
C++14
Python3
#include <bits/stdc++.h>using namespace std;void KswapPermutation(    int arr[], int n, int k){    for(int i=0;i<n-1;i++)    {        if( k>0)        {            int max = i;            for(int j=i+1;j<n;j++)            if(arr[j]>arr[max])            max = j;                     // this condition checks whether the max value has changed since when          // we started , or is it the same.          // We need to ignore the swap if the value is same.          // It means that the number ought to be present at the ith position , is already          // there.            if(max!=i)            {            int temp = arr[max];            arr[max] = arr[i];            arr[i] = temp;            k--;            }        }        else        break;    }}  // Driver codeint main(){    int arr[] = { 4, 5, 2, 1, 3 };    int n = sizeof(arr) / sizeof(arr[0]);    int k = 3;    KswapPermutation(arr, n, k);    cout << "Largest permutation after "         << k << " swaps:"<<endl;    for (int i = 0; i < n; ++i)        cout<<arr[i]<<" ";    return 0;}
def KswapPermutation(arr, n, k):    for i in range(0, n-1):        if(k > 0):            max = i            for j in range(i+1, n):                if(arr[j] > arr[max]):                    max = j             # this condition checks whether the max value has changed since when            # we started , or is it the same.            # We need to ignore the swap if the value is same.            # It means that the number ought to be present at the ith position , is already            # there.            if(max != i):                temp = arr[max]                arr[max] = arr[i]                arr[i] = temp                k = k-1         else:            break # Driver codearr = [4, 5, 2, 1, 3]n = len(arr)k = 3KswapPermutation(arr, n, k)print("Largest permutation after "+str(k) + " swaps:")for i in range(0, n):    print(arr[i], end=' ') # This code is contributed by Harsh Khatri
Largest permutation after 3 swaps:
5 4 3 2 1 
Complexity analysis :
Time complexity :  O(n^2) , because this approach utilizes selection sort
Space complexity : O(1) , because the sort is in place and no extra space is needed
Efficient approach: 
This is a greedy approach. The largest permutation is found when the largest elements are at the front of the array, i.e. the largest elements are sorted in decreasing order. There are at most k swaps so put the 1st, 2nd, 3rd, ..., kth largest element at their respective position.
Note: If the number of swaps allowed is equal to the size of the array, then there is no need to iterate over the whole array. The answer will simply be the reverse sorted array.
Algorithm: 
Create a HashMap or an array of length n to store element-index pair or map element to its index.Now run a loop k times.In each iteration swap the ith element with the element n – i. where i is the index or count of the loop. Also swap their position, i.e. update the hashmap or array. So in this step the largest element in remaining element is swapped to the front.Print the output array.
Create a HashMap or an array of length n to store element-index pair or map element to its index.
Now run a loop k times.
In each iteration swap the ith element with the element n – i. where i is the index or count of the loop. Also swap their position, i.e. update the hashmap or array. So in this step the largest element in remaining element is swapped to the front.
Print the output array.
Implementation 1: This uses simple arrays to arrive at the solution. 
C++
Java
Python3
C#
PHP
Javascript
// Below is C++ code to print largest// permutation after at most K swaps#include <bits/stdc++.h>using namespace std; // Function to calculate largest// permutation after atmost K swapsvoid KswapPermutation(    int arr[], int n, int k){    // Auxiliary dictionary of    // storing the position of elements    int pos[n + 1];     for (int i = 0; i < n; ++i)        pos[arr[i]] = i;     for (int i = 0; i < n && k; ++i) {        // If element is already i'th largest,        // then no need to swap        if (arr[i] == n - i)            continue;         // Find position of i'th        // largest value, n-i        int temp = pos[n - i];         // Swap the elements position        pos[arr[i]] = pos[n - i];        pos[n - i] = i;         // Swap the ith largest value with the        // current value at ith place        swap(arr[temp], arr[i]);         // decrement number of swaps        --k;    }} // Driver codeint main(){    int arr[] = { 4, 5, 2, 1, 3 };    int n = sizeof(arr) / sizeof(arr[0]);    int k = 3;     KswapPermutation(arr, n, k);    cout << "Largest permutation after "         << k << " swaps:n";    for (int i = 0; i < n; ++i)        printf("%d ", arr[i]);    return 0;}
// Below is Java code to print// largest permutation after// atmost K swapsclass GFG {     // Function to calculate largest    // permutation after atmost K swaps    static void KswapPermutation(        int arr[], int n, int k)    {         // Auxiliary dictionary of storing        // the position of elements        int pos[] = new int[n + 1];         for (int i = 0; i < n; ++i)            pos[arr[i]] = i;         for (int i = 0; i < n && k > 0; ++i) {             // If element is already i'th            // largest, then no need to swap            if (arr[i] == n - i)                continue;             // Find position of i'th largest            // value, n-i            int temp = pos[n - i];             // Swap the elements position            pos[arr[i]] = pos[n - i];            pos[n - i] = i;             // Swap the ith largest value with the            // current value at ith place            int tmp1 = arr[temp];            arr[temp] = arr[i];            arr[i] = tmp1;             // decrement number of swaps            --k;        }    }     // Driver method    public static void main(String[] args)    {         int arr[] = { 4, 5, 2, 1, 3 };        int n = arr.length;        int k = 3;         KswapPermutation(arr, n, k);         System.out.print(            "Largest permutation "            + "after " + k + " swaps:\n");         for (int i = 0; i < n; ++i)            System.out.print(arr[i] + " ");    }} // This code is contributed by Anant Agarwal.
# Python code to print largest permutation after K swaps def KswapPermutation(arr, n, k):     # Auxiliary array of storing the position of elements    pos = {}    for i in range(n):        pos[arr[i]] = i     for i in range(n):         # If K is exhausted then break the loop        if k == 0:            break         # If element is already largest then no need to swap        if (arr[i] == n-i):            continue         # Find position of i'th largest value, n-i        temp = pos[n-i]         # Swap the elements position        pos[arr[i]] = pos[n-i]        pos[n-i] = i         # Swap the ith largest value with the value at        # ith place        arr[temp], arr[i] = arr[i], arr[temp]         # Decrement K after swap        k = k-1 # Driver codearr = [4, 5, 2, 1, 3]n = len(arr)k = 3KswapPermutation(arr, n, k) # Print the answerprint ("Largest permutation after", k, "swaps: ")print (" ".join(map(str, arr)))
// Below is C# code to print largest// permutation after atmost K swaps.using System; class GFG {     // Function to calculate largest    // permutation after atmost K    // swaps    static void KswapPermutation(int[] arr,                                 int n, int k)    {         // Auxiliary dictionary of storing        // the position of elements        int[] pos = new int[n + 1];         for (int i = 0; i < n; ++i)            pos[arr[i]] = i;         for (int i = 0; i < n && k > 0; ++i) {             // If element is already i'th            // largest, then no need to swap            if (arr[i] == n - i)                continue;             // Find position of i'th largest            // value, n-i            int temp = pos[n - i];             // Swap the elements position            pos[arr[i]] = pos[n - i];            pos[n - i] = i;             // Swap the ith largest value with            // the current value at ith place            int tmp1 = arr[temp];            arr[temp] = arr[i];            arr[i] = tmp1;             // decrement number of swaps            --k;        }    }     // Driver method    public static void Main()    {         int[] arr = { 4, 5, 2, 1, 3 };        int n = arr.Length;        int k = 3;         KswapPermutation(arr, n, k);         Console.Write("Largest permutation "                      + "after " + k + " swaps:\n");         for (int i = 0; i < n; ++i)            Console.Write(arr[i] + " ");    }} // This code is contributed nitin mittal.
<?php// PHP code to print largest permutation// after atmost K swaps // Function to calculate largest// permutation after atmost K swapsfunction KswapPermutation(&$arr, $n, $k){     for ($i = 0; $i < $n; ++$i)        $pos[$arr[$i]] = $i;     for ($i = 0; $i < $n && $k; ++$i)    {        // If element is already i'th largest,        // then no need to swap        if ($arr[$i] == $n - $i)            continue;         // Find position of i'th largest        // value, n-i        $temp = $pos[$n - $i];         // Swap the elements position        $pos[$arr[$i]] = $pos[$n - $i];        $pos[$n - $i] = $i;         // Swap the ith largest value with the        // current value at ith place        $t = $arr[$temp];        $arr[$temp] = $arr[$i];        $arr[$i] = $t;                 // decrement number of swaps        --$k;    }} // Driver code$arr = array(4, 5, 2, 1, 3);$n = sizeof($arr);$k = 3; KswapPermutation($arr, $n, $k);echo ("Largest permutation after ");echo ($k);echo (" swaps:\n");for ($i = 0; $i < $n; ++$i){    echo ($arr[$i] );    echo (" ");} // This code is contributed// by Shivi_Aggarwal?>
<script>     // Below is Javascript code to print largest    // permutation after at most K swaps         // Function to calculate largest    // permutation after atmost K swaps    function KswapPermutation(arr, n, k)    {        // Auxiliary dictionary of        // storing the position of elements        let pos = new Array(n + 1);         for (let i = 0; i < n; ++i)            pos[arr[i]] = i;         for (let i = 0; i < n && k; ++i) {            // If element is already i'th largest,            // then no need to swap            if (arr[i] == n - i)                continue;             // Find position of i'th            // largest value, n-i            let temp = pos[n - i];             // Swap the elements position            pos[arr[i]] = pos[n - i];            pos[n - i] = i;             // Swap the ith largest value with the            // current value at ith place            let tmp1 = arr[temp];            arr[temp] = arr[i];            arr[i] = tmp1;             // decrement number of swaps            --k;        }    }      let arr = [ 4, 5, 2, 1, 3 ];    let n = arr.length;    let k = 3;      KswapPermutation(arr, n, k);    document.write("Largest permutation after " + k + " swaps:" + "</br>");    for (let i = 0; i < n; ++i)        document.write(arr[i] + " ");             </script>
Largest permutation after 3 swaps:n5 4 3 2 1 
Implementation 2: This uses a hashmap to arrive at the solution.
C++
Java
Python3
C#
Javascript
// C++ Program to find the// largest permutation after// at most k swaps using unordered_map.#include <bits/stdc++.h>#include <unordered_map>using namespace std; // Function to find the largest// permutation after k swapsvoid bestpermutation(    int arr[], int k, int n){    // Storing the elements and    // their index in map    unordered_map<int, int> h;    for (int i = 0; i < n; i++) {        h.insert(make_pair(arr[i], i));    }     // If number of swaps allowed    // are equal to number of elements    // then the resulting permutation    // will be descending order of    // given permutation.    if (n <= k) {        sort(arr, arr + n, greater<int>());    }    else {         for (int j = n; j >= 1; j--) {            if (k > 0) {                 int initial_index = h[j];                int best_index = n - j;                 // if j is not at it's best index                if (initial_index != best_index) {                     h[j] = best_index;                     // Change the index of the element                    // which was at position 0. Swap                    // the element basically.                    int element = arr[best_index];                    h[element] = initial_index;                    swap(                        arr[best_index],                        arr[initial_index]);                     // decrement number of swaps                    k--;                }            }        }    }} // Driver codeint main(){    int arr[] = { 3, 1, 4, 2, 5 };     // K is the number of swaps    int k = 10;     // n is the size of the array    int n = sizeof(arr) / sizeof(int);     // Function calling    bestpermutation(arr, k, n);     cout << "Largest possible permutation after "         << k << " swaps is ";    for (int i = 0; i < n; i++)        cout << arr[i] << " ";     return 0;}// This method is contributed by Kishan Mishra.
// Java Program to find the// largest permutation after// at most k swaps using unordered_map.import java.util.*;class GFG{   // Function to find the largest  // permutation after k swaps  static void bestpermutation(ArrayList<Integer> arr, int k, int n)  {     // Storing the elements and    // their index in map    HashMap<Integer, Integer> h =        new HashMap<Integer, Integer>();     for (int i = 0; i < n; i++)    {      h.put(arr.get(i), i);    }     // If number of swaps allowed    // are equal to number of elements    // then the resulting permutation    // will be descending order of    // given permutation.    if (n <= k) {      Collections.sort(arr, Collections.reverseOrder());     }    else {       for (int j = n; j >= 1; j--)      {        if (k > 0)        {           int initial_index = h.get(j);          int best_index = n - j;           // if j is not at it's best index          if (initial_index != best_index)          {            h.put(j, best_index);             // Change the index of the element            // which was at position 0. Swap            // the element basically.            int element = arr.get(best_index);            h.put(element, initial_index);            int temp = arr.get(best_index);            arr.set(best_index, arr.get(initial_index));            arr.set(initial_index, temp);             // decrement number of swaps            k--;          }        }      }    }  }   // Driver code  public static void main(String []args)  {     ArrayList<Integer> arr = new ArrayList<Integer>();    arr.add(3);    arr.add(1);    arr.add(4);    arr.add(2);    arr.add(5);     // K is the number of swaps    int k = 10;     // n is the size of the array    int n = arr.size();     // Function calling    bestpermutation(arr, k, n);     System.out.print("Largest possible permutation after " + k + " swaps is ");     for (int i = 0; i < n; i++)      System.out.print(arr.get(i) + " ");  }} // This code is contributed by rutvik_56.
# Python3 program to find the# largest permutation after# at most k swaps using unordered_map. # Function to find the largest# permutation after k swapsdef bestpermutation(arr, k, n):         # Storing the elements and    # their index in map    h = {}    for i in range(n):        h[arr[i]] = i     # If number of swaps allowed    # are equal to number of elements    # then the resulting permutation    # will be descending order of    # given permutation.    if (n <= k):        arr.sort()        arr.reverse()    else:                 for j in range(n, 0, -1):            if (k > 0):                initial_index = h[j]                best_index = n - j                 # If j is not at it's best index                if (initial_index != best_index):                    h[j] = best_index                     # Change the index of the element                    # which was at position 0. Swap                    # the element basically.                    element = arr[best_index]                    h[element] = initial_index                    arr[best_index], arr[initial_index] = (arr[initial_index],                                                           arr[best_index])                                                                                # Decrement number of swaps                    k -= 1 # Driver Codearr = [ 3, 1, 4, 2, 5 ] # K is the number of swapsk = 10 # n is the size of the arrayn = len(arr) # Function callingbestpermutation(arr, k, n) print("Largest possible permutation after",      k, "swaps is", end = " ")       for i in range(n):    print(arr[i], end = " ") # This code is contributed by divyesh072019
// C# Program to find the// largest permutation after// at most k swaps using unordered_map.using System;using System.Collections.Generic;class GFG {         // Function to find the largest    // permutation after k swaps    static void bestpermutation(List<int> arr, int k, int n)    {        // Storing the elements and        // their index in map        Dictionary<int, int> h =                         new Dictionary<int, int>();         for (int i = 0; i < n; i++) {            h.Add(arr[i], i);        }              // If number of swaps allowed        // are equal to number of elements        // then the resulting permutation        // will be descending order of        // given permutation.        if (n <= k) {            arr.Sort();            arr.Reverse();        }        else {                  for (int j = n; j >= 1; j--) {                if (k > 0) {                          int initial_index = h[j];                    int best_index = n - j;                          // if j is not at it's best index                    if (initial_index != best_index) {                              h[j] = best_index;                              // Change the index of the element                        // which was at position 0. Swap                        // the element basically.                        int element = arr[best_index];                        h[element] = initial_index;                        int temp = arr[best_index];                        arr[best_index] = arr[initial_index];                        arr[initial_index] = temp;                              // decrement number of swaps                        k--;                    }                }            }        }    }   static void Main() {    List<int> arr = new List<int>(new int[] {3, 1, 4, 2, 5 });      // K is the number of swaps    int k = 10;      // n is the size of the array    int n = arr.Count;      // Function calling    bestpermutation(arr, k, n);      Console.Write("Largest possible permutation after " + k + " swaps is ");    for (int i = 0; i < n; i++)        Console.Write(arr[i] + " ");  }} // This code is contributed by divyeshrabadiya07
<script> // JavaScript Program to find the// largest permutation after// at most k swaps using unordered_map. // Function to find the largest  // permutation after k swapsfunction bestpermutation(arr,k,n){    // Storing the elements and    // their index in map    let h =       new Map();    for (let i = 0; i < n; i++)    {      h.set(arr[i], i);    }      // If number of swaps allowed    // are equal to number of elements    // then the resulting permutation    // will be descending order of    // given permutation.    if (n <= k) {      arr.sort(function(a,b){return b-a;});    }    else {        for (let j = n; j >= 1; j--)      {        if (k > 0)        {            let initial_index = h[j];          let best_index = n - j;            // if j is not at it's best index          if (initial_index != best_index)          {            h.set(j, best_index);              // Change the index of the element            // which was at position 0. Swap            // the element basically.            let element = arr.get(best_index);            h.set(element, initial_index);            let temp = arr[best_index];            arr.set(best_index, arr[initial_index]);            arr.set(initial_index, temp);              // decrement number of swaps            k--;          }        }      }    }} // Driver codelet arr=[3,1,4,2,5];// K is the number of swapslet k = 10; // n is the size of the arraylet n = arr.length; // Function callingbestpermutation(arr, k, n); document.write("Largest possible permutation after " + k + " swaps is "); for (let i = 0; i < n; i++)    document.write(arr[i] + " ");  // This code is contributed by avanitrachhadiya2155 </script>
Largest possible permutation after 10 swaps is 5 4 3 2 1 
Complexity Analysis: 
Time Complexity: O(N). Only one traversal of the array is required.
Space Complexity: O(n). To store the new array O(n) space is required.
This article is contributed by Shubham Bansal. 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. 
nitin mittal
Shivi_Aggarwal
mishrakishan1
andrew1234
Akanksha_Rai
divyesh072019
divyeshrabadiya07
khushboogoyal499
rutvik_56
mukesh07
avanitrachhadiya2155
prachisoda1234
yadavtanishq2001
amartyaghoshgfg
khatriharsh281
hardikkoriintern
Arrays
Combinatorial
Greedy
Arrays
Greedy
Combinatorial
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Introduction to Arrays
K'th Smallest/Largest Element in Unsorted Array | Set 1
Subset Sum Problem | DP-25
Python | Using 2D arrays/lists the right way
Introduction to Data Structures
Write a program to print all permutations of a given string
Permutation and Combination in Python
Factorial of a large number
itertools.combinations() module in Python to print all possible combinations
Count of subsets with sum equal to X