Largest permutation after at most k swaps

Given a permutation of first n natural numbers as array and an integer k. Print the lexicographically largest permutation after at most k swaps

Input: arr[] = {4, 5, 2, 1, 3}
       k = 3
Output: 5 4 3 2 1
Explanation:
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

A Naive approach is to one by one generate 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. Problem of this approach is that it would be difficult to implement and will definitely time out for large value of N.

An Efficient approach is to think greedily. If we visualize the problem then we will get to know that largest permutation can only be obtained if it starts with n and continues with n-1, n-2,…. So we just need to put the 1st, 2nd, 3rd, …, kth largest element to their respective position.

C++

// Below is C++ code to print largest permutation
// after atmost K swaps
#include<bits/stdc++.h>
using namespace std;

// Function to calculate largest permutation after
// atmost K swaps
void 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 code
int 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;
}

Python

# 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 code
arr = [4, 5, 2, 1, 3]
n = len(arr)
k = 3
KswapPermutation(arr, N, K)

# Print the answer
print "Largest permutation after", K, "swaps: "
print " ".join(map(str,arr))
Output:
Largest permutation after 3 swaps:
5 4 3 2 1 

Time complexity: O(n)
Auxiliary space: O(n)

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

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

GATE CS Corner    Company Wise Coding Practice

Recommended Posts:







Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.