数组中唯一对之间所有差异的最小总和
给定一个由N个整数组成的数组arr[] ,任务是在更新数组arr[]后找到数组中唯一元素对之间所有绝对差的最小和。要更新数组,可以按任意顺序选择数组中的任意两个元素。从第一个元素中减去 1 并添加到第二个元素。此步骤可以重复任意次数。
例子:
Input: arr[]={1, 2, 3}
Output: 0
Explanation: Choosing 1 and 3 for updating the array, 3-1=2 and 1+1=2. So the updated array becomes arr[]={2, 2, 2}. Minimum possible sum of the absolute difference of pairs is 0+0+0=0.
Input: arr[]={0, 1, 1, 0}
Output: 4
Explanation: Choosing any two elements for updation will lead to increase in total sum of absolute differences. So the sum is 1+1+1+1+0+0=4.
方法:可以根据以下观察解决给定的问题:
- 为了最小化所有唯一对之间的绝对差之和,元素应尽可能接近。
- 为此,求总和S并将总和S除以N ,即val = S/N。
- 如果val是一个整数,那么问题就变得非常简单了,因为所有整数都可以转换为X 。
- 否则,一些元素说X将是刚好小于val 的整数,即floor(val) ,而其他元素将是ceil(val)。
- 要找到X 的值,请使用即使在更新数组的总和之后也是相同的事实。因此,使用以下等式求X的值。
x*(b-1) + N*b – x*b = S
=> x*b – x + N*b – x*b = S
=> N*b – x = S
=> x = N*b – S
- 例如
N = 10
arr[] = {8, 3, 6, 11, 5, 2, 1, 7, 10, 4}
Sum of all elements of the array, S=57
So, S/N = 5.7 means if all the elements are converted to 5.7, then the sum of all absolute differences b/w all unique pairs of elements will be minimized i.e, 0.
But converting all elements to 5.7 using the mentioned operation isn’t possible.
So, some elements will be 5 and the others will be 6.
Now, the question is how many elements will be 5. Let’s say x, then (N-x) will be 6 and in all this process sum will be always be conserved.
=> x*5 + (N-x)*6 = 57
=> -x = 57 – 60 (Putting the value of N as 10 and solving the equation)
-x = -3 => x=3
So, the converted array will be {5, 5, 5, 6, 6, 6, 6, 6, 6, 6}
- 现在会产生像 1 这样的差异的对是x*(Nx) 。
- 所以差异的总和也将是x*(Nx) 。
请按照以下步骤解决问题:
- 将变量sum初始化为0以将元素的总和存储在数组arr[]中。
- 使用变量i迭代范围[0, N]并执行以下步骤:
- 在变量sum中添加arr[i]的值。
- 将变量temp初始化为(float)S/N。
- 将a的值设置为temp 的底值。
- 将b的值设置为temp 的 ceil 值。
- 将x的值设置为b*N-sum以存储将发生分区的位置。
- 打印x*(Nx)的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to calculate the minimum
// sum of differences of pairs
void solve(int N, int arr[])
{
int a, b, S = 0, x;
for (int i = 0; i < N; i++) {
// Take sum of all elements
S = S + arr[i];
}
// Store s/n to a temporary float
// variable and typecast
// s/n to get exact float value
float temp = (float)S / N;
// take floor value of temp
a = floor(temp);
// take floor value of temp
b = ceil(temp);
// position where partition will happen
x = b * N - S;
// Total sum of differences
cout << x * (N - x);
}
// Driver Code
int main()
{
int arr[] = { 8, 3, 6, 11, 5, 2, 1, 7, 10, 4 };
int N = sizeof(arr) / sizeof(arr[0]);
solve(N, arr);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG
{
// Function to calculate the minimum
// sum of differences of pairs
static void solve(int N, int arr[])
{
int a, b, S = 0, x;
for (int i = 0; i < N; i++)
{
// Take sum of all elements
S = S + arr[i];
}
// Store s/n to a temporary float
// variable and typecast
// s/n to get exact float value
float temp =(float) S / N;
// take floor value of temp
a = (int) Math.floor(temp);
// take floor value of temp
b = (int)Math.ceil(temp);
// position where partition will happen
x = b * N - S;
// Total sum of differences
System.out.println(x * (N - x));
}
// Driver Code
public static void main (String[] args) {
int arr[] = { 8, 3, 6, 11, 5, 2, 1, 7, 10, 4 };
int N = arr.length;
solve(N, arr);
}
}
// This code is contributed by Potta Lokesh
Python3
# Python program for the above approach
import math
# Function to calculate the minimum
# sum of differences of pairs
def solve(N, arr):
a, b, S, x = 0, 0, 0, 0;
for i in range(0, N, 1):
# Take sum of all elements
S = S + arr[i];
# Store s/n to a temporary float
# variable and typecast
# s/n to get exact float value
temp = S / N;
# take floor value of temp
a = math.floor(temp);
# take floor value of temp
b = math.ceil(temp);
# position where partition will happen
x = b * N - S;
# Total sum of differences
print(x * (N - x));
# Driver Code
if __name__ == '__main__':
arr = [ 8, 3, 6, 11, 5, 2, 1, 7, 10, 4 ];
N = len(arr);
solve(N, arr);
# This code is contributed by 29AjayKumar
C#
using System;
public class GFG {
static void solve(int N, int[] arr)
{
int b, S = 0, x;
for (int i = 0; i < N; i++) {
// Take sum of all elements
S = S + arr[i];
}
// Store s/n to a temporary float
// variable and typecast
// s/n to get exact float value
float temp = (float)S / N;
// take floor value of temp
b = (int)Math.Ceiling(temp);
// position where partition will happen
x = b * N - S;
// Total sum of differences
Console.WriteLine(x * (N - x));
}
// Driver Code
static public void Main()
{
int[] arr = { 8, 3, 6, 11, 5, 2, 1, 7, 10, 4 };
int N = arr.Length;
solve(N, arr);
}
}
// This code is contributed by maddler.
Javascript
21
时间复杂度: O(N)
辅助空间: O(1)