【问题标题】:Find Maximum Distance between two points查找两点之间的最大距离
【发布时间】:2012-09-01 23:15:24
【问题描述】:

昨天,我出现在一个采访中。我被困在一个问题中,我在这里问的是同样的问题。

给定一个数组,显示 x 轴上的点,有 N 个点。还赠送了M币。

Remember N >= M

你必须最大化任意两点之间的最小距离。

Example: Array : 1 3 6 12
         3 coins are given.
         If you put coins on 1, 3, 6 points Then distance between coins are : 2, 3 
         So it gives 2 as answer 
         But we can improve further
         If we put coins at 1, 6, 12 points.
         Then distances are 5, 6
         So correct answer is : 5

请帮助我,因为我完全陷入了这个问题。

【问题讨论】:

  • 几天前刚刚回答了这个问题:stackoverflow.com/questions/12278528/…
  • 顺便说一句,我给出的解决方案具有多项式复杂性,并且解决方案始终是最优的。
  • @ElKamina 我认为我的解决方案可能更快
  • @chacham15 我不阅读这个论坛上的代码。无论如何,谢谢!
  • @ElKamina 添加了一些文字解释,因为似乎人们不想阅读伪代码,哈哈。

标签: algorithm recursion dynamic-programming greedy number-theory


【解决方案1】:

您可以使用 greyy 算法:选择有序序列的第一个点和最后一个点(因为这是可能的最大距离)。然后你选择最接近它们平均值的点(因为任何其他答案都会在一侧给出更小的距离),而不是选择更大的分区。然后根据需要重复多次。

【讨论】:

  • WebMonster,我也讲过同样的方法。首先对数组进行排序,然后将点放在起始点和结束点上,然后将第三个点放在起点和终点的中间附近。但是我们提出第四点的地方
  • 重复什么?你把第四个硬币放在哪里?第五?即使只有 4 个硬币和许多等距的点,这个算法显然是错误的,因为它会将第三个硬币放在不应该有硬币的中间。
  • 使用最大的分区,我认为这可能类似于二进制搜索问题但我必须考虑一下:)
  • @WebMonster,你能告诉我你是如何决定第四枚硬币应该放在哪里的吗?
【解决方案2】:

您必须使用动态编程。因为,您需要一个最佳答案。 您的问题类似于“Change -making of the coin”问题。像这个问题一样,你没有硬币,你想找到最小距离。(而不是最小的硬币)。

您可以阅读以下链接:Change Coin problem & Dynamic Programming

【讨论】:

  • 如何通过保持最优性约束将问题拆分为子问题?
  • 对不起!!!这是我的错。动态规划不适合。我在最佳答案的背景下思考。但是这里的问题不能分成子问题。对不起,伙计们。
【解决方案3】:

这是我的 O(N2) 方法。首先,生成所有可能的距离;

int dist[1000000][3], ndist = 0;
for(int i = 0; i < n; i ++) {
    for(int j = i + 1; j < n; j ++) {
        dist[ndist][0] = abs(points[i] - points[j]);
        dist[ndist][1] = i; //save the first point
        dist[ndist][2] = j; //save the second point
    }
}

现在按降序排列距离:

sort(dist, dist + ndist, cmp);

cmp 在哪里:

bool cmp(int x[], int y[]) {
    return (x[0] > y[0]);
}

扫过数组,添加点,只要你没有选择m点:

int chosen = 0;
int ans;
for(int i = 0; i < ndist; i ++) {
    int whatadd = (!visited[dist[i][1]]) + (!visited[dist[i][2]); //how many new points we'll get if we take this one
    if(chosen + whatadd > m) {
        break;
    }
    visited[dist[i][1]] = 1;
    visited[dist[i][2]] = 1;
    chosen += whatadd;
    ans = dist[i][0]; //ans is the last dist[i][0] chosen, since they're sorted in decreasing order
}
if(chosen != m) {
    //you need at most one extra point, choose the optimal available one
    //left as an exercise :)
}

希望对你有所帮助!

【讨论】:

  • 这与我发布的解决方案相同,只是我在线性时间内完成了
  • @chacham15 实际上你的解决方案是不同的,你只是在排序后考虑连续点之间的差异。
  • 对,你基本上是在使用我一次解决的蛮力
  • @chacham15 请在此测试您的解决方案:N = 5, M = 3,要点是:1, 4, 7, 100, 200。输出应该是 99。
  • 我的解决方案得出了相同的结论(尽管伪代码中缺少-1,抱歉)
猜你喜欢
  • 2019-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-20
相关资源
最近更新 更多