阵列中唯一的一对之间的所有差异的最小总和

113 阅读4分钟

阵列中所有独特配对之间的最小差异之和

  • 最后更新 : 2021年8月6日

给定一个由N个整数组成的数组 arr[],任务是找到更新数组 **arr[]**后数组中唯一的一对元素之间所有绝对差异的最小和。为了更新数组,可以按任何顺序从数组中选择任何两个元素。从第一个元素中减去1,然后加到第二个元素中。这个步骤可以重复任何次数。

例子。

输入: arr[]={1, 2, 3}
**输出。**0
解释。 选择1和3来更新数组,3-1=2,1+1=2。所以更新后的数组成为arr[]={2, 2, 2}。成对的绝对差值的最小可能之和是0+0+0=0。

输入: arr[]={0, 1, 1, 0}
**输出。**4
解释。 选择任何两个元素进行更新都会导致绝对差值的总和增加。所以总和是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}
数组中所有元素的总和,S=57
所以,S/N=5.7意味着如果所有的元素都转换为5.7,那么所有元素对之间的绝对差值之和将达到最小,即0。
但是使用上述操作将所有元素转换为5.7是不可能的。
所以,一些元素将是5,其他将是6。

现在,问题是有多少元素会是5。比方说x,那么(N-x)将是6,在所有这个过程中,总和将永远是保守的。
=> x*5 + (N-x)*6 = 57
=> -x = 57 - 60 (将N的值设为10,然后解方程)
-x = -3 => x=3
因此,转换后的数组将是{5, 5, 5, 6, 6, 6, 6, 6, 6}。

  • 现在,将给出一个像1一样的差异的对是x*(N-x)
  • 所以差值的总和也将是x*(N-x)

按照下面的步骤来解决这个问题。

  • 将变量sum初始化为0,以存储数组 **arr[]**中的元素之和。
  • 使用变量i对范围 **[0, N]**进行迭代,并执行以下步骤。
    • 在变量sum中加入arr[i]的值**。**
  • 将变量temp初始化为**(float)S/N。**
  • a的值设为temp底限值
  • b的值设为temp上限
  • x的值设为b*N-sum,以存储将发生分区的位置。
  • 打印**x*(N-x)**的值作为结果。

下面是上述方法的实现。

C++

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to calculate the minimum
// sum of diffrences 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 temperory 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;
}

输出

21

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

读者请注意!现在不要停止学习。掌握所有重要的DSA概念。 DSA自学课程以适合学生的价格掌握所有重要的DSA概念,并成为行业的准备者。 要完成从学习语言到DS Algo以及更多的准备工作,请参考 完整的面试准备课程.

如果你想参加专家的现场课程 ,请参考 面向在职人士的DSA现场课程面向学生的竞争性编程直播课程.

我的个人笔记 arrow_drop_up

保存