给定的阵列ARR []由N个整数的,任务是找到通过交换任一对元件(X,Y),使得交换的成本的(以升序排序的给定阵列ARR [] X最小成本+ 是) 。
例子:
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
方法:根据以下观察可以解决给定的问题:
- 通过在当前数组的每个第i个元素和已排序数组之间形成边来形成有向图。
- 可以观察到,每个组件总是会形成一个循环,因为每个节点的入度和出度都等于1 。
- 因此,想法是分别对每个循环的元素进行排序。
插图:
- 假设给定的数组是 {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递减sum 。
- 现在找到通过使用局部最小值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 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 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 现场工作专业课程和学生竞争性编程现场课程。