解释算法背后的数学

时间:2017-06-06 00:02:29

标签: javascript algorithm math

给定一个整数排序的数组a,找到一个整数x,其值为

abs(a [0] - x)+ abs(a [1] - x)+ ... + abs(a [a.length - 1] - x) 是最小的(这里abs表示绝对值)。 如果有多个可能的答案,请输出最小的答案。

实施例

对于a = [2,4,7],输出应为 absoluteValuesSumMinimization(a)= 4。

我能够通过强制解决这个问题,但后来我发现了这个

function absoluteValuesSumMinimization(A) {
    return A[Math.ceil(A.length/2)-1];
}

希望了解其工作原理/原因。

3 个答案:

答案 0 :(得分:1)

让我们把它分解。

A.length/2返回一半长度,用于查找数组的中间部分。对于偶数长度数组,这将位于中间的右侧。对于奇数长度数组,它将是中间数。

如果需要,

Math.ceil(A.length/2)向上舍入,因此数组5的中间值为2.5 - >这使奇数长度数组偏离一个。

Math.ceil(A.length/2)-1下降了一个索引。这可以纠正所有阵列的逐个错误。

所有这个解决方案都说,在一个偶数长度的数组中,你正在寻找的值总是位于中间的左边。在奇数长度的数组中,总是是中间项。

这很直观。从每个项目中减去数组中的中间项将始终产生最低的总和。在偶数长度数组中,两个中心项将始终产生相同的总和,因此最小的数字将位于中心的左侧。

要查看此内容,请从此强力解决方案中删除console.log条评论并尝试多个数组:

function absoluteValuesSumMinimization(ints) {
  const vals = [];

  ints.forEach(int => {
    const sum = ints.reduce((accum, next) => {
      return accum + Math.abs(next  - int);
    }, 0);

    vals.push(sum);
  });

  // console.log(vals);
  const lowest = Math.min(...vals);
  return ints[vals.indexOf(lowest)];
}

答案 1 :(得分:0)

假设我们有n 1 值,其中a[i] - x为负数,n 2 值为a[i] - x为正。

如果我们将整数x增加1,那么绝对值的总和会增加n 1 - n 2

如果我们将整数x减1,则绝对值的总和会增加n 2 - n 1

因此,只要n 1 和n 2 不相等,我们就可以通过向一个方向移动x来减少绝对值的总和或者另一种,取决于n 1 - n 2 是正还是负。

因此,至少必须有n 1 = n 2 ie 需要与许多{{ 1}}小于a[i]的值,因为大于x

答案 2 :(得分:0)

我们可以按如下方式编写问题:

http://imgur.com/I1fvjuL

当我们计算出N时,第一项成为列表的平均值" a":

N(mean(a) - a j

如果我们假设排序列表,则最小化此数量的值是最接近术语mean(a)的值,即列表的中位数。

Math.ceil(A.length / 2)-1只返回列表的中间值,即排序列表的中位数。