【问题标题】:How do I calculate the k nearest numbers to the median?如何计算最接近中位数的 k 个数字?
【发布时间】:2012-12-27 11:30:51
【问题描述】:

我有一个包含 n 个成对不同元素的数组和一个 1

现在我正在寻找一种算法来计算k 与数字数组中位数的绝对差最小的数字。 我需要线性复杂度 (O(n))。

我的方法:

我找到中位数:

  • 我对数字进行排序
  • 我得到了中间元素,或者如果元素的数量 id 甚至是中间和圆形中两个元素的平均值。

之后:

  • 我获取每个数字并找到与中位数的绝对距离。这些结果我保存在不同的数组中
  • 我对新得到的数组进行排序。
  • 我取结果数组的前 k 个元素,我就完成了。

我不知道我的解决方案是否在O(n) 中,也不知道我的想法是否正确。有人可以验证吗?有人可以告诉我如何在 O(n) 中解决它吗?

【问题讨论】:

  • 这是 StackOverflow 而不是代码工厂......当你遇到困难时我们会帮助你,但你必须开始......
  • 不,你的排序破坏了 O(n)。
  • 那不排序怎么解决?
  • 如果你使用排序,那么你有O(nlogn)
  • 我已经修正了你问题中的语法,希望你不要介意。

标签: arrays algorithm median


【解决方案1】:

你可以这样解决你的问题:

您可以在O(n), w.g. 中找到中位数。使用O(n)nth_element algorithm。

您遍历所有元素,每个元素都用一对替换:<the absolute difference to the median>, <element's value>。再次使用n = k 执行 nth_element。应用此算法后,您可以保证在新数组中首先具有绝对差的k 最小元素。你把他们的索引和完成!

另一方面,您的算法使用排序,这使它成为O(nlogn)。

EDIT:请求的示例:

设数组为[14, 6, 7, 8, 10, 13, 21, 16, 23]。

  • 在找到中位数的步骤之后,它将被重新排序为:[8, 7, 9, 10, 13, 16, 23, 14, 21],请注意数组未排序,但中位数 (13) 仍然正好在中间。
  • 现在让我们进行让您感到困惑的配对替换:我们创建一个新的配对数组:[<abs(14-13), 14>, <abs(6-13), 6>, <abs(7-13), 7>, <abs(8-13), 8>, <abs(10-13), 10>, <abs(13-13), 13>, <abs(21-13), 21>, <abs(16-13), 16>, <abs(23-13), 23>。这样我们就得到了数组:[<1, 14>, <7, 6>, <6, 7>, <5, 8>, <3, 10>, <0, 13>, <8, 21>, <3, 16>, <10, 23>
  • 如果例如k 是 4,我们再次创建 nth_element(使用每对的第一个元素进行比较)并获得:[<1, 14>, <3, 16>, <0, 13>, <3, 10>, <8, 21>, <7, 6>, <10, 23>, <6, 7>, <5, 8>] 所以您搜索的数字是前 4 对的第二个元素:14, 16 , 13 和 10

【讨论】:

  • 你能给我举个例子吗?因为我无法获得“一对替换”怎么办?
  • @Boris:您的描述说“元素的索引”,但您的工作示例使用了元素的值。两者都可以(如果您使用索引,那么您可以在原始输入数组的末尾查找它,假设步骤 1 分区是在副本上完成的),但您可能希望它们相同。此外,如果您最后需要的只是该值,那么您可以稍微简化一下并完成所有操作,只需使用比较器运行 nth_element 来比较中位数与绝对值的差异。
猜你喜欢
  • 2014-07-29
  • 2012-11-17
  • 1970-01-01
  • 2018-05-09
  • 2018-03-26
  • 2018-04-25
  • 2012-07-19
  • 2014-08-08
  • 2021-08-17
相关资源
最近更新 更多