给定一个包含整数值的数组,我们需要以最小的成本使该数组的所有值等于某个整数值,其中将数组值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