代码之家  ›  专栏  ›  技术社区  ›  Abhijit Sarkar

最小化到最远点的距离

  •  0
  • Abhijit Sarkar  · 技术社区  · 7 年前

    这个问题是在一次面试中被问到的。

    假设你想搬家,并拥有一套便利设施, 希望从新家轻松访问。你找到了一个 你喜欢的街区,每个街区都没有或更多的便利设施。 你怎么选择住得最远的街区 到您列表中任何便利设施的距离最小化?

    例如,假设您的列表包含学校、杂货店和街区 如下:

    1:餐厅、杂货店

    2:电影院

    3:学校

    4:

    5:学校

    理想的选择是块2,这样到 杂货店和最近的学校各1所。住在1区或3区 将使其中一个距离为零,而另一个距离为2。

    我想出了一个简单的解决方案,如下面的伪代码所示:

    max = minus infinity
    min = plus infinity    
    
    for r in requirements:
      for i in blocks:
        for j in blocks:
          if j.amenities contains r:
            max = maximum {max, dist(i, j)}
        if max < min:
          live_at = i
    

    如果 n 是块的数量,此算法的时间复杂性为 O(n^2) ,假设需求列表比 n . 我们能做得更好吗?

    This 尽管我不清楚答案,但问题似乎是相似的。它指的是一张纸,从“在C中心画一个圆”开始,没有任何指示 c 是。

    0 回复  |  直到 7 年前
        1
  •  0
  •   Photon    7 年前

    是的,我们可以在O(n*k log n)中完成,其中n是块数,k是便利设施数。

    便利设施列表很小,所以创建阵列列表 对于存在这种便利设施的每个便利设施和存储块位置。

    例如,使用您提供的示例:

    • [餐厅]=1
    • [杂货店]=1
    • [电影院]=2
    • A[“学校”]=3,5

    现在我们可以循环遍历所有块并使用下界(二进制搜索) 找到最近的街区,为每个需要的便利设施提供所需的便利设施。

    然后选择一个距离所需便利设施最小的街区。

        2
  •  0
  •   user58697    7 年前

    解决方案是包含所有便利设施的最短块子阵列。请注意,最左边的块的便利性必须只存在一次;最右边的块也是如此。居住的街区就在中间。

    两个指针的技术很适合。

    有一个数组 k 计数器,当前窗口中每个便利设施一个,将其初始化为所有零。做两个指针, left right ,进入块数组;最初两个都指向数组的开头。然后,执行步骤

    • 加速:前进 正确的 指针,计算它经过的便利设施,直到遇到每个便利设施。

    • 从左边修剪:向前 左边 指针,相应地递减计数器,只要两个计数器都未达到 0 . 你有一个初步的解决方案;记录下来。

    • 在循环中,

      • 预付款 左边 一次,减少相关计数器。其中一些变为0。
      • 从左边配平:继续前进 左边 只要没有其他计数器转到0。
      • 预付款 正确的 直到所有的柜台都满了。这是另一个尝试性的解决方案,保留最好的。
      • 继续循环,直到右指针不再前进。

    假设任何给定的街区没有太多的便利设施,这将运行 O(n) time, and o(k)`空格。

    正确性的证明留作练习。