【问题标题】:Shortest path in a custom binary search tree自定义二叉搜索树中的最短路径
【发布时间】:2015-07-04 04:54:34
【问题描述】:

这是来自编码竞赛的问题

原始问题可以在这里找到http://www.olympiad.org.za/olympiad/wp-content/uploads/2014/03/2013-PO-Question-Paper.pdf 问题 5

穿过大厅的最短路径 [作者:Hulsbos High 的 Alan Smithee]

大厅里挤满了一排排椅子, 但每一排正好有两把椅子 失踪。每排椅子都有编号 从 1 到 100。编写一个程序来计算 从前面到前面的最短路径的长度 大厅的后面。 每把椅子宽 1 个单位,每排 1 个单位 深(从椅子的前面到椅子的前面 后面的椅子)。无法移动 对角线。你可以从前面的任何间隙开始 前排并在最后一排的任何间隙后面结束。 你总是从一个缺口的中间走过。 图示是穿过大厅的最短路径, 五排椅子。图中的大厅是 只有 10 把椅子宽,而不是 100 把。 输入中的第一个数字将包含 number n – 行数。接下来的 n 行 将有两个数字,用空格分隔, 指出差距在哪里。 例子 输入: 5 3 6 2 8 4 5 7 8 3 10

我认为我有一个我认为可以工作的有效算法,但我不确定如何在 Java 中实现它。

我想要做的是将每个选择分解成一个搜索树,例如,如果用户输入是:

行数:3

空间:4 7 2 9 8 11

制作 2 棵搜索树:

              4                               7            
       2           9                     2           9
     8   11      8   11             8      11     8      11

然后找到每个节点之间差异最小的路径 所以在这种情况下,最短路径将在第二棵树 7->9->8 中,总距离为 5 (||7-9|-8|) 所以我的问题是

  1. 考虑到问题,这个算法是否可以接受

  2. 我将如何在 java 中实现这个算法或另一个算法

@JuanLopes 以这个例子为例(0 代表一个空格)。

第 6 行:0 2 3 4 5 6 0 8 9

第 5 行:0 2 3 4 5 6 0 8 9

第 4 行:1 2 3 0 5 6 0 8 9

第 3 行:1 2 3 0 5 6 0 8 9

第 2 行:1 2 3 0 5 6 0 8 9

第 1 行:1 2 3 0 5 6 0 8 9

我从您的算法中了解到,它单独查看每一行。因此,通过第 1-4 行,每个空间到下一行之间的距离是相等的,但是当你到达第 5 行时,如果你沿着所有 4 都丢失的路径走,与沿着所有缺少 7s,您的解决方案是否考虑到这一点?

【问题讨论】:

  • 实际上,您给出的示例的答案是 6,而不是 5。(7 到 9 = 2)+(9 到 8 = 1)+ 3 行 = 6。

标签: java algorithm recursion binary-search-tree graph-theory


【解决方案1】:

您描述的算法是不可接受的,因为最多可以有 100 行,所以如果在每一行中树中的节点数加倍,那么在最坏的情况下,您的树中将有 2^101 个节点.

这个问题可以通过简单的动态规划来解决,在每一步中,您必须选择第一个和第二个间隙之间的最小值:

T(0, j) = 1
T(i, j) = 1+min(
              abs(pos(i, j)-pos(i-1, 0)) + T(i-1, 0),
              abs(pos(i, j)-pos(i-1, 1)) + T(i-1, 1))

其中i 是第i 行,j01,表示我们在最后一回合选择了哪个间隙。下面是一些示例 Java 实现:

import static java.lang.Math.abs;
import static java.lang.Math.min;

public class Main {
    public static int solve(int[][] P) {
        int a = 1, b = 1;
        for (int i = 1; i < P.length; i++) {
            int na = 1 + min(
                    abs(P[i][0] - P[i - 1][0]) + a,
                    abs(P[i][0] - P[i - 1][1]) + b);

            int nb = 1 + min(
                    abs(P[i][1] - P[i - 1][0]) + a,
                    abs(P[i][1] - P[i - 1][1]) + b);

            a = na;
            b = nb;
        }
        return min(a, b);
    }

    public static void main(String... args) {
        System.out.println(solve(new int[][]{
                {3, 6},
                {2, 8},
                {4, 5},
                {7, 8},
                {3, 10},
        }));


        System.out.println(solve(new int[][]{
                {4, 7},
                {2, 9},
                {8, 11}
        }));
    }
}

【讨论】:

  • 好吧,您认为该算法效率低下是对的,但我相当确定该算法不会 100% 有效。例如,如果您在第 11 行的 10 行的空间之间的距离相等,如果您走错了路,它会改变,在这种情况下会花费您更长的时间,因为该算法只查看下一步而不是第 n 步
  • 你能详细说明这个例子吗?我相信这个算法可以解决这个问题。不是因为我那么信任自己,而是因为这是一个经典的动态规划问题。但我只能确定我是否使用比赛数据进行测试:你知道在哪里可以找到它吗?
  • 请看问题的修改:D
  • @TamirShklaz 是的,它需要。如果仔细观察,算法不会选择要走的路径。相反,它计算从前一行中的两个选项中选择每行中的两个选项的最小值。顺便说一句,您示例中的答案又是 6。
  • 哦,我现在明白了。非常感谢,您知道我可以用来进一步学习动态编程的任何好的指南
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多