阵列中所有独特配对之间的最小差异之和
- 最后更新 : 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 pairsvoid solve(int N,int arr[]){int a, b, S = 0, x;for (int i = 0; i < N; i++) {// Take sum of all elementsS = S + arr[i];}// Store s/n to a temperory float// variable and typecast// s/n to get exact float valuefloat temp = (float)S / N;// take floor value of tempa =floor(temp);// take floor value of tempb =ceil(temp);// position where partition will happenx = b * N - S;// Total sum of differencescout << x * (N - x);}// Driver Codeint 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
保存