📌  相关文章
📜  使所有数组元素等于最小成本

📅  最后修改于: 2021-05-04 10:59:16             🧑  作者: Mango

给定一个包含整数值的数组,我们需要以最小的成本使该数组的所有值等于某个整数值,其中将数组值x更改为y的成本为abs(xy)。

例子 :

Input  : arr[] = [1, 100, 101]
Output : 100
We can change all its values to 100 with minimum cost,
|1 - 100| + |100 - 100| + |101 - 100| = 100

Input  : arr[] = [4, 6]
Output : 2
We can change all its values to 5 with minimum cost,
|4 - 5| + |5 - 6| = 2

这个问题可以通过在改变目标相等值的同时观察成本来解决,即,当目标相等值改变时,我们将看到成本的变化。可以观察到,随着我们增加目标均等值,总成本会下降到一个极限,然后开始增加,即相对于目标均等值的成本图呈U形,而成本图呈U形,三元搜索可以应用于此搜索空间,我们的目标是获得曲线的最底点,该点代表最小的成本。我们将数组的最小和最大值作为搜索空间的极限,然后将继续跳过搜索空间的1/3部分,直到到达U形曲线的最低点。

请参阅下面的代码以更好地理解。

C++
// C++ program to find minimum cost to
// make all elements equal
#include 
using namespace std;
 
// Utility method to compute cost, when
// all values of array are made equal to X
int computeCost(int arr[], int N, int X)
{
    int cost = 0;
    for (int i = 0; i < N; i++)
        cost += abs(arr[i] - X);
    return cost;
}
 
// Method to find minimum cost to make all
// elements equal
int minCostToMakeElementEqual(int arr[], int N)
{
    int low, high;
    low = high = arr[0];
 
    // setting limits for ternary search by
    // smallest and largest element
    for (int i = 0; i < N; i++) {
        if (low > arr[i])
            low = arr[i];
        if (high < arr[i])
            high = arr[i];
    }
 
    /* loop until difference between low and high
       become less than 3, because after that
       mid1 and mid2 will start repeating
    */
    while ((high - low) > 2) {
 
        // mid1 and mid2 are representative array
        // equal values of search space
        int mid1 = low + (high - low) / 3;
        int mid2 = high - (high - low) / 3;
 
        int cost1 = computeCost(arr, N, mid1);
        int cost2 = computeCost(arr, N, mid2);
 
        // if mid2 point gives more total cost,
        // skip third part
        if (cost1 < cost2)
            high = mid2;
 
        // if mid1 point gives more total cost,
        // skip first part
        else
            low = mid1;
    }
 
    // computeCost gets optimum cost by sending
    // average of low and high as X
    return computeCost(arr, N, (low + high) / 2);
}
 
// Driver code to test above method
int main()
{
    int arr[] = { 1, 100, 101 };
    int N = sizeof(arr) / sizeof(int);
    cout << minCostToMakeElementEqual(arr, N);
    return 0;
}


Java
// JAVA Code for Make all array elements
// equal with minimum cost
class GFG {
 
    // Utility method to compute cost, when
    // all values of array are made equal to X
    public static int computeCost(int arr[], int N,
                                  int X)
    {
        int cost = 0;
        for (int i = 0; i < N; i++)
            cost += Math.abs(arr[i] - X);
        return cost;
    }
 
    // Method to find minimum cost to make all
    // elements equal
    public static int minCostToMakeElementEqual(int arr[],
                                                int N)
    {
        int low, high;
        low = high = arr[0];
 
        // setting limits for ternary search by
        // smallest and largest element
        for (int i = 0; i < N; i++) {
            if (low > arr[i])
                low = arr[i];
            if (high < arr[i])
                high = arr[i];
        }
 
        /* loop until difference between low and high
           become less than 3, because after that
           mid1 and mid2 will start repeating
        */
        while ((high - low) > 2) {
            // mid1 and mid2 are representative array
            // equal values of search space
            int mid1 = low + (high - low) / 3;
            int mid2 = high - (high - low) / 3;
 
            int cost1 = computeCost(arr, N, mid1);
            int cost2 = computeCost(arr, N, mid2);
 
            // if mid2 point gives more total cost,
            // skip third part
            if (cost1 < cost2)
                high = mid2;
 
            // if mid1 point gives more total cost,
            // skip first part
            else
                low = mid1;
        }
 
        // computeCost gets optimum cost by sending
        // average of low and high as X
        return computeCost(arr, N, (low + high) / 2);
    }
 
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        int arr[] = { 1, 100, 101 };
        int N = arr.length;
        System.out.println(minCostToMakeElementEqual(arr, N));
    }
}
// This code is contributed by Arnav Kr. Mandal.


Python3
# Python3 program to find minimum 
# cost to make all elements equal
 
# Utility method to compute cost, when
# all values of array are made equal to X
def computeCost(arr, N, X):
 
    cost = 0
    for i in range(N):
        cost += abs(arr[i] - X)
    return cost
 
 
# Method to find minimum cost to
# make all elements equal
def minCostToMakeElementEqual(arr, N):
 
    low = high = arr[0]
 
    # Setting limits for ternary search
    # by smallest and largest element
    for i in range(N):
     
        if (low > arr[i]): low = arr[i]
        if (high < arr[i]): high = arr[i]
 
 
    # loop until difference between low and
    # high become less than 3, because after
    # that mid1 and mid2 will start repeating
    while ((high - low) > 2):
     
        # mid1 and mid2 are representative
        # array equal values of search space
        mid1 = low + (high - low) // 3
        mid2 = high - (high - low) // 3
 
        cost1 = computeCost(arr, N, mid1)
        cost2 = computeCost(arr, N, mid2)
 
        # if mid2 point gives more total
        # cost, skip third part
        if (cost1 < cost2):
            high = mid2
 
        # if mid1 point gives more total
        # cost, skip first part
        else:
            low = mid1
     
 
    # computeCost gets optimum cost by
    # sending average of low and high as X
    return computeCost(arr, N, (low + high) // 2)
 
# Driver code
arr = [1, 100, 101]
N = len(arr)
print(minCostToMakeElementEqual(arr, N))
 
# This code is contributed by Anant Agarwal.


C#
// C# Code to Make all array elements
// equal with minimum cost
using System;
 
class GFG {
 
    // Utility method to compute cost, when
    // all values of array are made equal to X
    public static int computeCost(int[] arr, int N,
                                             int X)
    {
        int cost = 0;
        for (int i = 0; i < N; i++)
            cost += Math.Abs(arr[i] - X);
        return cost;
    }
 
    // Method to find minimum cost to
    // make all elements equal
    public static int minCostToMakeElementEqual(int[] arr,
                                                    int N)
    {
        int low, high;
        low = high = arr[0];
 
        // setting limits for ternary search by
        // smallest and largest element
        for (int i = 0; i < N; i++) {
            if (low > arr[i])
                low = arr[i];
            if (high < arr[i])
                high = arr[i];
        }
 
        /* loop until difference between low and high
        become less than 3, because after that
        mid1 and mid2 will start repeating
        */
        while ((high - low) > 2) {
             
            // mid1 and mid2 are representative array
            // equal values of search space
            int mid1 = low + (high - low) / 3;
            int mid2 = high - (high - low) / 3;
 
            int cost1 = computeCost(arr, N, mid1);
            int cost2 = computeCost(arr, N, mid2);
 
            // if mid2 point gives more total cost,
            // skip third part
            if (cost1 < cost2)
                high = mid2;
 
            // if mid1 point gives more total cost,
            // skip first part
            else
                low = mid1;
        }
 
        // computeCost gets optimum cost by sending
        // average of low and high as X
        return computeCost(arr, N, (low + high) / 2);
    }
 
    /* Driver program to test above function */
    public static void Main()
    {
        int[] arr = { 1, 100, 101 };
        int N = arr.Length;
        Console.Write(minCostToMakeElementEqual(arr, N));
    }
}
 
// This code is contributed by nitin mittal


PHP
 $arr[$i])
            $low = $arr[$i];
        if ($high < $arr[$i])
            $high = $arr[$i];
    }
 
    /* loop until difference between
    low and high become less than 3,
    because after that mid1 and mid2
    will start repeating */
    while (($high - $low) > 2)
    {
        // mid1 and mid2 are representative
        // array equal values of search space
        $mid1 = $low + (floor($high - $low) / 3);
        $mid2 = $high - ($high - $low) / 3;
 
        $cost1 = computeCost($arr, $N, $mid1);
        $cost2 = computeCost($arr, $N, $mid2);
 
        // if mid2 point gives more total
        // cost, skip third part
        if ($cost1 < $cost2)
            $high = $mid2;
 
        // if mid1 point gives more
        // total cost, skip first part
        else
            $low = $mid1;
    }
 
    // computeCost gets optimum cost by
    // sending average of low and high as X
    return computeCost($arr, $N, ($low +
                                  $high) / 2);
}
 
// Driver Code
$arr = array( 1, 100, 101 );
$N = sizeof($arr) / sizeof($arr[0]);
echo minCostToMakeElementEqual($arr, $N);
 
// This code is contributed by nitin mittal.
?>


Javascript


C++
#include 
using namespace std;
 
// This function assumes that a[] is
// sorted. If a[] is not sorted, we need
// to sort it first.
int minCostToMakeElementEqual(int a[], int n)
{
 
    // If there are odd elements, we choose
    // middle element
    int y;
    if (n % 2 == 1)
        y = a[n / 2];
 
    // If there are even elements, then we choose
    // the average of middle two.
    else
        y = (a[n / 2] + a[(n - 2) / 2]) / 2;
 
    // After deciding the final value, find the
    // result.
    int s = 0;
    for(int i = 0; i < n; i++)
        s += abs(a[i] - y);
         
    return s;
}
 
// Driver code
int main()
{
    int a[] = { 1, 100, 101 };
    int n = sizeof(a) / sizeof(a[0]);
     
    cout << (minCostToMakeElementEqual(a, n));
}
 
// This code is contributed by chitranayal


Java
import java.io.*;
import java.util.*;
 
class GFG{
 
// This function assumes that a[] is
// sorted. If a[] is not sorted, we need
// to sort it first.   
public static int minCostToMakeElementEqual(int a[],
                                            int n)
{
     
    // If there are odd elements, we choose
    // middle element
    int y;
     
    if (n % 2 == 1)
        y = a[n / 2];
     
    // If there are even elements, then we
    // choose the average of middle two.
    else
        y = (a[n / 2] + a[(n - 2) / 2]) / 2;
     
    // After deciding the final value,
    // find the result.
    int s = 0;
     
    for(int i = 0; i < n; i++)
        s += Math.abs(a[i] - y);
     
    return s;
}
 
// Driver code
public static void main (String[] args)
{
    int a[] = { 1, 100, 101 };
    int n = a.length;
     
    System.out.println(minCostToMakeElementEqual(a, n));
}
}
 
// This code is contributed by parascoding


Python3
# This function assumes that a[] is
# sorted. If a[] is not sorted, we need
# to sort it first.
def minCostToMakeElementEqual(a):
    l = len(a)
 
    # If there are odd elements, we choose
    # middle element
    if (l%2 == 1):
        y = a[l//2]
 
    # If there are even elements, then we choose
    # the average of middle two.
    else:
        y = (a[l//2] + a[(l-2)//2])//2
 
    # After deciding the final value, find the
    # result.
    s = 0
    for i in range(l):
        s += abs(a[i]-y)
    return s
 
# Driver code
a = [1, 100, 101]
print(minCostToMakeElementEqual(a))


C#
using System;
using System.Collections.Generic;
 
class GFG{
     
// This function assumes that a[] is
// sorted. If a[] is not sorted, we need
// to sort it first.   
static int minCostToMakeElementEqual(int[] a,
                                     int n)
{
     
    // If there are odd elements, we choose
    // middle element
    int y;
      
    if (n % 2 == 1)
        y = a[n / 2];
      
    // If there are even elements, then we
    // choose the average of middle two.
    else
        y = (a[n / 2] + a[(n - 2) / 2]) / 2;
      
    // After deciding the final value,
    // find the result.
    int s = 0;
      
    for(int i = 0; i < n; i++)
        s += Math.Abs(a[i] - y);
      
    return s;
}
 
// Driver code
static void Main()
{
    int[] a = { 1, 100, 101 };
    int n = a.Length;
      
    Console.WriteLine(
        minCostToMakeElementEqual(a, n));
}
}
 
// This code is contributed by divyeshrabadiya07


Javascript


输出:
100

替代解决方案
进行几何思考。假设数组元素是x轴上的坐标。问题减少到找到另一个坐标,从而使该选择和其他坐标之间的距离之和最小。
观察到:如果坐标数为奇数,则y =中间元素。如果是偶数,则y是中间2个坐标之间的任何数字。说输入= [a,b,c,d]。输出是b和c之间的任何数字,包括b和c。因此,成本是总和,既然我们选择了y,就可以很容易地计算出总和。总和|(y-ai)|为了我

编写代码确实很容易。

C++

#include 
using namespace std;
 
// This function assumes that a[] is
// sorted. If a[] is not sorted, we need
// to sort it first.
int minCostToMakeElementEqual(int a[], int n)
{
 
    // If there are odd elements, we choose
    // middle element
    int y;
    if (n % 2 == 1)
        y = a[n / 2];
 
    // If there are even elements, then we choose
    // the average of middle two.
    else
        y = (a[n / 2] + a[(n - 2) / 2]) / 2;
 
    // After deciding the final value, find the
    // result.
    int s = 0;
    for(int i = 0; i < n; i++)
        s += abs(a[i] - y);
         
    return s;
}
 
// Driver code
int main()
{
    int a[] = { 1, 100, 101 };
    int n = sizeof(a) / sizeof(a[0]);
     
    cout << (minCostToMakeElementEqual(a, n));
}
 
// This code is contributed by chitranayal

Java

import java.io.*;
import java.util.*;
 
class GFG{
 
// This function assumes that a[] is
// sorted. If a[] is not sorted, we need
// to sort it first.   
public static int minCostToMakeElementEqual(int a[],
                                            int n)
{
     
    // If there are odd elements, we choose
    // middle element
    int y;
     
    if (n % 2 == 1)
        y = a[n / 2];
     
    // If there are even elements, then we
    // choose the average of middle two.
    else
        y = (a[n / 2] + a[(n - 2) / 2]) / 2;
     
    // After deciding the final value,
    // find the result.
    int s = 0;
     
    for(int i = 0; i < n; i++)
        s += Math.abs(a[i] - y);
     
    return s;
}
 
// Driver code
public static void main (String[] args)
{
    int a[] = { 1, 100, 101 };
    int n = a.length;
     
    System.out.println(minCostToMakeElementEqual(a, n));
}
}
 
// This code is contributed by parascoding

Python3

# This function assumes that a[] is
# sorted. If a[] is not sorted, we need
# to sort it first.
def minCostToMakeElementEqual(a):
    l = len(a)
 
    # If there are odd elements, we choose
    # middle element
    if (l%2 == 1):
        y = a[l//2]
 
    # If there are even elements, then we choose
    # the average of middle two.
    else:
        y = (a[l//2] + a[(l-2)//2])//2
 
    # After deciding the final value, find the
    # result.
    s = 0
    for i in range(l):
        s += abs(a[i]-y)
    return s
 
# Driver code
a = [1, 100, 101]
print(minCostToMakeElementEqual(a))

C#

using System;
using System.Collections.Generic;
 
class GFG{
     
// This function assumes that a[] is
// sorted. If a[] is not sorted, we need
// to sort it first.   
static int minCostToMakeElementEqual(int[] a,
                                     int n)
{
     
    // If there are odd elements, we choose
    // middle element
    int y;
      
    if (n % 2 == 1)
        y = a[n / 2];
      
    // If there are even elements, then we
    // choose the average of middle two.
    else
        y = (a[n / 2] + a[(n - 2) / 2]) / 2;
      
    // After deciding the final value,
    // find the result.
    int s = 0;
      
    for(int i = 0; i < n; i++)
        s += Math.Abs(a[i] - y);
      
    return s;
}
 
// Driver code
static void Main()
{
    int[] a = { 1, 100, 101 };
    int n = a.Length;
      
    Console.WriteLine(
        minCostToMakeElementEqual(a, n));
}
}
 
// This code is contributed by divyeshrabadiya07

Java脚本


输出
100