最小化数组的每个元素与整数K之间的差异总和

时间:2014-05-04 04:04:25

标签: algorithm math optimization minimum

给定一个N个非负整数的数组A,找到一个整数k,这样每个元素与k的差值之和最小。
求和(abs(A [i] - k)),1< = i< = N,或简称为 | A [1] - k | + | A [2] - k | + | A [3] - k | + ... + | A [N] - k |

我的方法:

low = minimumValueInArray(A);
high= maximumValueInArray(A);
ans = Infinite;
for (k = low; k <= high; k++) {
    temp = 0;
    for (i = 1; i <= N; i++) {
        temp += abs(A[i] - K);
    }
    ans = min(ans, temp);
}
return ans;

这只是蛮力的方法,试图解决K的所有价值。我们可以优化它 这样做的更聪明的方法是什么?

参考:这是我背后的逻辑 Codejam Round 1B problem

3 个答案:

答案 0 :(得分:3)

我基本上得到了中位数。要最小化成本函数,请采用导数。

enter image description here

要查找成本函数的最小值,请找出导数为零的位置。成本函数在任何地方都不是连续可微的,但它是分段可微的。设S = A和si的排序数是第i个最大数。

案例1.如果m是奇数

将会有楼层(m / 2)ai小于中位数且楼层(m / 2)ai大于中位数。选择x =中位数,给出-m / 2 + 0 + m / 2 = 0。

enter image description here

案例2.如果m是偶数

对于si和s之间的值,导数将为零(i + 1); i = m / 2。然后可以选择任何数字k,以便

enter image description here

简单的例子 1 2 4 50

选择2:1 + 0 + 2 + 48 = 51

选择4:3 + 2 + 0 + 46 = 51

选择3:2 + 1 + 1 + 47 = 51

所以任意选择s(m / 2)

对于更好的算法,O(NlogN)您可以对数字进行排序,然后根据需要从上面选择(m + 1)/ 2或m / 2,或者您可以使用可以计算答案的kth largest element在O(N)。

答案 1 :(得分:1)

给定一组数字A_1,...,A_N,已知(参见例如http://homepages.gac.edu/~holte/courses/mcs256/problems/median.pdf)中位数最小化绝对偏差之和。

由于你有一个整数数组,所以:

(a)N为奇数,中位数为整数m,您将k设为。

(b)N是偶数,中位数是两个整数a和b的平均值。在这种情况下,事实证明a和b之间的所有数字都使绝对偏差的总和最小化。所以你可以选择k作为a,b或中间的任何整数(如果有的话)。

例如,如果数字是1,3,4,6,9 - 中位数是4,则将k设置为。 如果数字是4,7,12,15,则中位数是(7 + 12)/ 2,你可以将k设置为7到12之间的任何数字。例如,k = 7给出总偏差(7-4)+(7 -7)+(12-7)+(15-7)= 16且k = 12给出总偏差(12-4)+(12-7)+(12-12)+(15-12)= 16。

答案 2 :(得分:-1)

您可以以数字线上的点的形式表示数组中的所有值。

例如,数字行上的点可能如下所示:

_____________________ 4 ___________ 7 _______________________ 12 ___________ 15

所以根据问题定义,我们可以说数字线上与所有点等距的点应该给出正确的答案。

所以你要做的就是找到所有数字的平均值。将答案作为更接近平均值的整数返回。例如,对于2.66返回3,对于2.2返回2,对于2.5返回2或3中的任何一个。

运行时间:O(N)来计算数字的平均值。

相关问题