我试图了解一种算法,该算法给定数组 A 和整数 x ,该算法返回需要添加到<的元素的最小数量em> A 以使 x 为中位数。
算法如下:
考虑中位数始终是位置(n-1)/ 2的元素
n := |A|
m := 0
for i := 1 to n:
if (A[i] < x) then:
m++
if (m < n - m) then:
return (n - 2 * m)
else:
return (2 * m – n + 1)
我知道,如果m等于nm,则数组大小是偶数,因此我们可以在(n-1)/ 2位置添加所需的中位数,这将是我们的新中位数。
我正在努力解决m小于n-m的情况,我们返回(n-2m)
或m大于n-m,然后返回(2 * m-n + 1)
**为什么这是真的?
如果您能提供一个证据,或者用简单的语言解释这将非常有帮助,我找不到证据!**
答案 0 :(得分:1)
我怀疑您误解了中位数是位置(n - 1) / 2
上的元素的含义。并不是说中值元素就是该元素在数组中的确切位置。相反,如果要对数组进行排序,则该元素将位于该位置。
例如,考虑数组
[31, 41, 59, 26, 53, 58, 97]
想象我们要使数字93为中值。让我们考虑一下要实现这一目标必须要做的事情。首先,以93为中位数,我们需要将其添加到数组中,如下所示:
[31, 41, 59, 26, 53, 58, 97, 93]
^^
现在,如果我们要对数组进行排序,那么93将位于哪个位置?让我们实际对数组进行排序以找出:
[26, 31, 41, 53, 58, 59, 93, 97]
^^
请注意,它位于数组中的位置6。那不是数组的中间,为了使该元素最终位于中间位置,我们需要插入一串更多的值,这些值在93之后,足以填充数组,以使93位于中间。例如,我们可以添加一些额外的99,如下所示:
[26, 31, 41, 53, 58, 59, 93, 97, 99, 99, 99, 99, 99]
^^ ^^ ^^ ^^ ^^ ^^
因此,在这种情况下,我们必须向数组中添加总共五个元素,以使93为中位数。
现在,这是一个要考虑的问题:为什么我们得到五个答案?其原因如下。按照算法的表示法,我们需要确保小于93的元素数量(将由m
表示)等于大于93的元素数量。 n - m
给出了数组中当前存在的大于93的值,因为这是数组的所有元素,减去小于93的元素。
因此,假设我们将93本身与大于93的k
元素添加到数组中,以尝试将93放置在中间位置。根据以上所述,我们需要使小于93(m
)的元素数必须比整个数组中大于或等于93({{1 }},这些元素已经大于或等于93,再加上n - m
,即我们添加的额外元素的数量)。这里的-1项说明了这样一个事实,当我们进行除法运算以计算中位数时,我们会四舍五入。那意味着我们有
m-1 = n-m + k
或者,
k = 2m-n + 1
嘿,看!它是k
,这是在2*m - n + 1
≥m
的情况下返回的结果,这意味着该数字大于或等于数组元素的一半以上。
另一方面,让我们回到原始数组,如下所示:
n - m
想象一下,我们要使27为中值元素。我们先添加27,如下所示:
[31, 41, 59, 26, 53, 58, 97]
现在,如果我们对元素进行排序,则会得到以下内容:
[31, 41, 59, 26, 53, 58, 97, 23]
^^
这不在中间位置,因此我们将不得不添加更多元素以填充数组。假设添加一堆较小的元素来填充内容,例如:
[26, 27, 31, 41, 53, 58, 59, 97]
^^
这次我们好像又需要五个元素。这是为什么?和以前一样,假设我们向该数组添加了[13, 13, 13, 13, 26, 27, 31, 41, 53, 58, 59, 97]
^^ ^^ ^^ ^^ ^^
个元素。我们需要拥有它
少于27(k
)个元素的数量加上(m
)中添加的元素的数量少于
大于或等于27(k
)的元素数减去1,因为新添加的27将算作大于或等于其自身的元素之一。
换句话说,我们需要
m + k = n-m,
或者那个
k = n-2m。
这使我们构成第二种情况的n - m
。
所以总结一下-这里出现的数学运算是因为我们试图填充数组以使包含要添加的数字的一面与较小的一面具有相同的长度,而该运算的数学方式取决于是否我们在数组的前一半或后一半。
希望这会有所帮助!