Minimize cost to sort an Array by swapping any pair of element (X, Y) with cost as (X + Y)

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 arrayint 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 Codeint 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 approachclass 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 arraydef 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 approachusing System;using System.Collections.Generic;Â
class GFG{     // Function to find the minimum cost to// sort the arraystatic 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 codepublic 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 zambiatek!




