Given an array arr[] consisting of N integers, the task is to find the minimum cost to sort the given array arr[] in ascending order by swapping any pair of elements (X, Y) such that the cost of swapping is (X + Y).
Examples:
Input: arr[] = {3, 2, 1}
Output: 4
Explanation:
Following are the swapping of array elements performed to sort the array:
- Swapping the array elements at index 0 and 2 modifies the array to {1, 2, 3}. The cost of this swapping operation is (arr[0] + arr[2]) = (3 + 1) = 4.
After the above steps, the given array is sorted and the total cost is 4, which is the minimum among all possible combinations of swapping.
Input: arr[] = {7, 9, 15}
Output: 0
Approach:Â The given problem can be solved based on the following observations:Â Â
- Form a directed graph by forming edges between every ith element of the current array and the sorted array.
- It can be observed that every component will always form a cycle as there every node will have in-degree and out-degree equal to 1.
- Therefore, the idea is to sort the elements of each cycle separately.
Illustration:
- Suppose the given array is {8, 4, 5, 3, 2, 7}. The sorted array will be equal to the {2, 3, 4, 5, 7, 8}.
- For the above array, the graph will contain two components which are cycles.
- If two elements are swapped in a cycle, of length K > 1 such that at least 1 element of this cycle will go to its destination. Then after the swap, it will be split into two cycles, one with length K – 1 and another one with length 1.
- For the given array, If 2 and 8 are swapped of 2 ? 8 ? 7 ? 2 cycles. 2 will go to its destination, and 7 ? 8 ? 7 will form a smaller cycle.
- Therefore, the minimum number of swaps needed to sort a cycle of size K is equal to the (K-1).
- It can be observed that each swap will add two elements to the cost. So 2 × (K – 1) elements will be added to the cost and there are K elements. So some elements will be added multiple times to the cost.
- Therefore, the idea is to, swap with the minimum value of a cycle with every other element to place them at the correct positions. Then in the final cost, every element will be added once and the minimum element will be added K – 1 time. So this is the optimal approach to solve a cycle.
- For sorting a cycle there are two choices: either to use only the local minimum of the cycle or to use both local and overall minimum of the array.
Follow the steps below to solve the problem:
- Initialize a variable res as 0 to store the total cost.
- Copy every element of arr[] to another array, say copyArr[] and sort copyArr[] in ascending order.
- Initialize a hashmap say place and store array elements and the correct position of it in the sorted array as key-value pair.
- Also, Initialize an array, visited[]Â of size N, and mark all its entries as false.
- Iterate over the array, arr[] using the variable i, and perform the following steps:
- If visited[i] is true then continue.
- If the element visited index is visited true and perform the following steps:
- If place[arr[i]] is equal to i then mark visited[i], true and continue.
- Initialize a variable say min_value as arr[i] and sum as 0, to store the minimum value of the current cycle and the sum of the elements of the cycle.
- Also, initialize a variable j as i to iterate over the cycle and a variable num as 0 to store the count of numbers in the cycle.
- Iterate until visited[j] is not true and in each iteration perform the following steps:
- Increment sum by arr[j] and num by 1 and then mark the visited[j] as true.
- Update min_value to min(min_value, arr[j]). And then assign value of place[arr[j]] to j.
- Decrement sum by the min_value.
- Now find the cost obtained by using the local minimum, min_value, and store it in a variable say Cost1.
- Cost1 = sum + min_val*(num-1).
- Now find the cost obtained by using the global minimum, copyArr[0], and store it in a variable say Cost2.
- Cost2 = copyArr[0] * (num + 1) + 2 * min_val+ sum
- Now increment res by min(Cost1, Cost2).
- After completing the above steps, print the res as the total cost.
Below is the implementation of the above approach:
C++
// C++ program for the above approach Â
#include <bits/stdc++.h> using namespace std; Â
// Function to find the minimum cost to // sort the array int findMinimumCost( int arr[], int N) {     // Stores the required result     int res = 0; Â
    // Create 2 arrays     int copyArr[N], visited[N]; Â
    for ( int i = 0; i < N; ++i) {         copyArr[i] = arr[i];         visited[i] = false ;     } Â
    // Sort the array, copyArr[] in     // increasing order     sort(copyArr, copyArr + N); Â
    // Map the numbers to their desired     // place after sorting     map< int , int > place; Â
    // Store the original places of the     // elements in map     for ( int i = 0; i < N; ++i) {         place[copyArr[i]] = i;     } Â
    // Iterate in the range [0, N-1]     for ( int i = 0; i < N; ++i) { Â
        // If the ith index is not visited         if (visited[i] == false ) { Â
            // If the original place and             // the place in sorted array             // is same then only mark this             // element as visited             if (place[arr[i]] == i) {                 visited[i] = true ;                 continue ;             } Â
            // Else a new cycle is present             int min_val = arr[i], cost1, cost2;             int num = 0;             int sum = 0;             int j = i; Â
            // Iterate while the nodes             // in the current cycle is             // not visited             while (visited[j] == false ) { Â
                // Increment sum by arr[j]                 sum += arr[j];                 num++; Â
                // Update the min_val value                 if (arr[j] < min_val) {                     min_val = arr[j];                 } Â
                // Mark j as visited                 visited[j] = true ; Â
                // Place j at its                 // original place                 j = place[arr[j]];             } Â
            // Sum of all numbers of             // cycle other than minimum             sum -= min_val; Â
            // Cost from local minimum             cost1 = sum + min_val * (num - 1); Â
            // Cost from overall minimum             cost2 = copyArr[0] * (num + 1) + 2 * min_val                     + sum; Â
            // Add the lower cost to             // the final result             if (cost1 < cost2) {                 res += cost1;             }             else {                 res += cost2;             }         }     } Â
    // Print the minimum cost     return res; } Â
// Driver Code int main() { Â Â Â Â int arr[] = { 3, 2, 1 }; Â Â Â Â int N = ( sizeof (arr) / sizeof ( int )); Â Â Â Â cout << findMinimumCost(arr, N); Â
    return 0; } |
Java
import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; Â
//Java program for above approach class GFG{ Â
    // Function to find the minimum cost to // sort the array     static int findMinimumCost( int [] arr, int N)     {         // Stores the required result         int res = 0 ; Â
        // Create 2 arrays         int [] copyArr = new int [N];         boolean [] visited = new boolean [N]; Â
        for ( int i = 0 ; i < N; ++i) {             copyArr[i] = arr[i];             visited[i] = false ;         } Â
        // Sort the array, copyArr[] in         // increasing order         Arrays.sort(copyArr); Â
        // Map the numbers to their desired         // place after sorting         Map<Integer, Integer> place = new HashMap<>(); Â
        // Store the original places of the         // elements in map         for ( int i = 0 ; i < N; ++i) {             place.put(copyArr[i],i);         } Â
        // Iterate in the range [0, N-1]         for ( int i = 0 ; i < N; ++i) { Â
            // If the ith index is not visited             if (visited[i] == false ) { Â
                // If the original place and                 // the place in sorted array                 // is same then only mark this                 // element as visited                 if (place.get(arr[i]) == i) {                     visited[i] = true ;                     continue ;                 } Â
                // Else a new cycle is present                 int min_val = arr[i], cost1, cost2;                 int num = 0 ;                 int sum = 0 ;                 int j = i; Â
                // Iterate while the nodes                 // in the current cycle is                 // not visited                 while (visited[j] == false ) { Â
                    // Increment sum by arr[j]                     sum += arr[j];                     num++; Â
                    // Update the min_val value                     if (arr[j] < min_val) {                         min_val = arr[j];                     } Â
                    // Mark j as visited                     visited[j] = true ; Â
                    // Place j at its                     // original place                     j = place.get(arr[j]);                 } Â
                // Sum of all numbers of                 // cycle other than minimum                 sum -= min_val; Â
                // Cost from local minimum                 cost1 = sum + min_val * (num - 1 ); Â
                // Cost from overall minimum                 cost2 = copyArr[ 0 ] * (num + 1 ) + 2 * min_val                         + sum; Â
                // Add the lower cost to                 // the final result                 if (cost1 < cost2) {                     res += cost1;                 }                 else {                     res += cost2;                 }             }         } Â
        // Print the minimum cost         return res;     } Â
    // Driver Code     public static void main(String[] args) {         int [] arr = { 3 , 2 , 1 };         int N = arr.length;         System.out.println(findMinimumCost(arr, N)); Â
    } } Â
// This code is contributed by hritikrommie. |
Python3
# Python program for the above approach Â
# Function to find the minimum cost to # sort the array def findMinimumCost(arr, N):     # Stores the required result     res = 0 Â
    # Create 2 arrays     copyArr = [ 0 ] * N     visited = [ 0 ] * N Â
    for i in range (N):         copyArr[i] = arr[i]         visited[i] = False Â
    # Sort the array, copyArr[] in     # increasing order     copyArr.sort() Â
    # Map the numbers to their desired     # place after sorting     place = {} Â
    # Store the original places of the     # elements in map     for i in range (N):         place[copyArr[i]] = i Â
    # Iterate in the range [0, N-1]     for i in range (N): Â
        # If the ith index is not visited         if (visited[i] = = False ): Â
            # If the original place and             # the place in sorted array             # is same then only mark this             # element as visited             if (place[arr[i]] = = i):                 visited[i] = True                 continue Â
            # Else a new cycle is present             min_val = arr[i]             num = 0             sum = 0             j = i Â
            # Iterate while the nodes             # in the current cycle is             # not visited             while (visited[j] = = False ): Â
                # Increment sum by arr[j]                 sum + = arr[j]                 num + = 1 Â
                # Update the min_val value                 if (arr[j] < min_val):                     min_val = arr[j] Â
                # Mark j as visited                 visited[j] = True Â
                # Place j at its                 # original place                 j = place[arr[j]] Â
            # Sum of all numbers of             # cycle other than minimum             sum - = min_val Â
            # Cost from local minimum             cost1 = sum + min_val * (num - 1 ) Â
            # Cost from overall minimum             cost2 = copyArr[ 0 ] * (num + 1 ) + 2 * min_val + sum Â
            # Add the lower cost to             # the final result             if (cost1 < cost2):                 res + = cost1             else :                 res + = cost2 Â
    # Print the minimum cost     return res Â
Â
# Driver Code Â
arr = [ 3 , 2 , 1 ] N = len (arr) print (findMinimumCost(arr, N)) Â
Â
# This code is contributed by gfgking |
C#
// C# program for the above approach using System; using System.Collections.Generic; Â
class GFG{      // Function to find the minimum cost to // sort the array static int findMinimumCost( int [] arr, int N) {          // Stores the required result     int res = 0; Â
    // Create 2 arrays     int [] copyArr = new int [N];     int [] visited = new int [N]; Â
    for ( int i = 0; i < N; ++i)     {         copyArr[i] = arr[i];         visited[i] = 0;     } Â
    // Sort the array, copyArr[] in     // increasing order     Array.Sort(copyArr); Â
    // Map the numbers to their desired     // place after sorting     Dictionary< int ,                int > place = new Dictionary< int ,                                            int >(); Â
    // Store the original places of the     // elements in map     for ( int i = 0; i < N; ++i)     {         place[copyArr[i]] = i;     } Â
    // Iterate in the range [0, N-1]     for ( int i = 0; i < N; ++i)     {                  // If the ith index is not visited         if (visited[i] == 0)         {                          // If the original place and             // the place in sorted array             // is same then only mark this             // element as visited             if (place[arr[i]] == i)             {                 visited[i] = 1;                 continue ;             } Â
            // Else a new cycle is present             int min_val = arr[i], cost1, cost2;             int num = 0;             int sum = 0;             int j = i; Â
            // Iterate while the nodes             // in the current cycle is             // not visited             while (visited[j] == 0)             {                                  // Increment sum by arr[j]                 sum += arr[j];                 num++; Â
                // Update the min_val value                 if (arr[j] < min_val)                 {                     min_val = arr[j];                 } Â
                // Mark j as visited                 visited[j] = 1; Â
                // Place j at its                 // original place                 j = place[arr[j]];             } Â
            // Sum of all numbers of             // cycle other than minimum             sum -= min_val; Â
            // Cost from local minimum             cost1 = sum + min_val * (num - 1); Â
            // Cost from overall minimum             cost2 = copyArr[0] * (num + 1) +                              2 * min_val + sum; Â
            // Add the lower cost to             // the final result             if (cost1 < cost2)             {                 res += cost1;             }             else             {                 res += cost2;             }         }     } Â
    // Print the minimum cost     return res; }      // Driver code public static void Main() {     int [] arr = { 3, 2, 1 };     int N = arr.Length;          Console.WriteLine(findMinimumCost(arr, N)); } } Â
// This code is contributed by sanjoy_62 |
Javascript
<script> Â
       // JavaScript program for the above approach Â
Â
       // Function to find the minimum cost to        // sort the array        function findMinimumCost(arr, N) {            // Stores the required result            let res = 0; Â
           // Create 2 arrays            let copyArr = Array(N);            let visited = Array(N); Â
           for (let i = 0; i < N; ++i) {                copyArr[i] = arr[i];                visited[i] = false ;            } Â
           // Sort the array, copyArr[] in            // increasing order            copyArr.sort( function (a, b) { return a - b; }); Â
           // Map the numbers to their desired            // place after sorting            let place = new Map(); Â
           // Store the original places of the            // elements in map            for (let i = 0; i < N; ++i) {                place.set(copyArr[i], i);            } Â
           // Iterate in the range [0, N-1]            for (let i = 0; i < N; ++i) { Â
               // If the ith index is not visited                if (visited[i] == false ) { Â
                   // If the original place and                    // the place in sorted array                    // is same then only mark this                    // element as visited                    if (place.get(arr[i]) == i) {                        visited[i] = true ;                        continue ;                    } Â
                   // Else a new cycle is present                    let min_val = arr[i], cost1, cost2;                    let num = 0;                    let sum = 0;                    let j = i; Â
                   // Iterate while the nodes                    // in the current cycle is                    // not visited                    while (visited[j] == false ) { Â
                       // Increment sum by arr[j]                        sum += arr[j];                        num++; Â
                       // Update the min_val value                        if (arr[j] < min_val) {                            min_val = arr[j];                        } Â
                       // Mark j as visited                        visited[j] = true ; Â
                       // Place j at its                        // original place                        j = place.get(arr[j]);                    } Â
                   // Sum of all numbers of                    // cycle other than minimum                    sum -= min_val; Â
                   // Cost from local minimum                    cost1 = sum + min_val * (num - 1); Â
                   // Cost from overall minimum                    cost2 = copyArr[0] * (num + 1) + 2 * min_val                        + sum; Â
                   // Add the lower cost to                    // the final result                    if (cost1 < cost2) {                        res += cost1;                    }                    else {                        res += cost2;                    }                }            } Â
           // Print the minimum cost            return res;        } Â
       // Driver Code Â
       let arr = [3, 2, 1];        let N = arr.length;        document.write(findMinimumCost(arr, N)); Â
Â
   // This code is contributed by Potta Lokesh    </script> |
4
Â
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!