📌  相关文章
📜  通过交换成本为 (X + Y) 的任意一对元素 (X, Y) 来最小化排序数组的成本

📅  最后修改于: 2021-10-25 05:02:43             🧑  作者: Mango

给定的阵列ARR []N个整数的,任务是找到通过交换任一对元件(X,Y),使得交换的成本的以升序排序的给定阵列ARR [] X最小成本+ 是)

例子:

方法:根据以下观察可以解决给定的问题:  

  1. 通过在当前数组的每个i元素和已排序数组之间形成边来形成有向图。
  2. 可以观察到,每个组件总是会形成一个循环,因为每个节点的入度和出度都等于1
  3. 因此,想法是分别对每个循环的元素进行排序。

插图:

  • 假设给定的数组是 {8, 4, 5, 3, 2, 7}。排序后的数组将等于 {2, 3, 4, 5, 7, 8}。
  • 对于上述数组,该图将包含两个循环组件。

  • 如果两个元素在一个循环中交换,长度K > 1 ,则该循环中至少有1 个元素将到达其目的地。然后在交换之后,它将被分成两个周期,一个长度为K – 1 ,另一个长度为1
  • 对于给定的数组,如果 2 和 8 交换了 2 → 8 → 7 → 2 个周期。 2 会到达目的地,7 → 8 → 7 会形成一个较小的循环。

  • 因此,对大小为K的循环进行排序所需的最小交换次数等于(K-1)
  • 可以观察到,每次交换都会为成本增加两个元素。所以2 × (K – 1) 个元素将被添加到成本中,并且有K 个元素。因此,某些元素将多次添加到成本中。
  • 因此,我们的想法是,将循环的最小值与每个其他元素交换,以将它们放置在正确的位置。然后在最终成本中,每个元素都会添加一次,最小元素将添加K-1次。所以这是解决循环的最佳方法。
  • 对循环进行排序有两种选择:要么仅使用循环的局部最小值,要么同时使用数组的局部和整体最小值。

请按照以下步骤解决问题:

  • 将变量res初始化为0以存储总成本。
  • arr[] 的每个元素复制到另一个数组,比如copyArr[]并按升序对copyArr[]进行排序。
  • 初始化一个 hashmap 说放置和存储数组元素以及它在排序数组中的正确位置作为键值对。
  • 此外,初始化一个数组,大小为N 的visited[] ,并将其所有条目标记为false。
  • 使用变量i迭代数组arr[] ,并执行以下步骤:
    • 如果visited[i]为真,则继续。
    • 如果元素被访问的索引被访问为,则执行以下步骤:
    • 如果place[arr[i]]等于i,则标记visited[i], true 并继续。
    • 将变量 say min_value初始化为arr[i]并将sum初始化为0,以存储当前循环的最小值和循环元素的总和。
    • 此外,将变量j初始化为i以迭代循环,将变量num初始化为0以存储循环中的数字计数。
    • 迭代直到visited[j]不为,在每次迭代中执行以下步骤:
      • sum增加arr[j]并将num增加1 ,然后将visited[j]标记为true
      • min_value更新为min(min_value, arr[j]) 。然后将place[arr[j]] 的值赋给j
    • min_value递减总和
    • 现在找到通过使用局部最小值min_value获得的成本,并将其存储在一个变量中,比如Cost1
      • COST1 =总和+ MIN_VAL *(NUM-1)。
    • 现在找到通过使用全局最小值copyArr[0]获得的成本,并将其存储在一个变量中,比如Cost2
      • Cost2 = copyArr[0] * (num + 1) + 2 * min_val+ sum
    • 现在将res增加min(Cost1, Cost2)。
  • 完成上述步骤后,打印res作为总成本。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
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 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 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 curent 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 place = new Dictionary();
 
    // 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


输出:
4

时间复杂度: O(N*log N)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程