Algorithm 在到达目的地之前,迷宫需要多少更改?

Algorithm 在到达目的地之前,迷宫需要多少更改?,algorithm,Algorithm,我遇到了这个面试问题。第一部分内容如下: 给您的矩阵包含字母“U”、“D”、“L”、“R”和“X”U'允许你向上移动,'L'允许向左移动,等等。'X'是 目的地检查是否有可能从目的地到达目的地 左上角 这一部分很容易用DFS完成。不过,我很难理解第二部分: 您需要进行多少次编辑,例如更改“U”->“L”,以便 到达X 我假设这可以通过修改BFS来完成,BFS计算我们违背指定方向的次数。有人能给点提示吗?只有一条路径,所以从一开始就迭代它,并将您访问的每个方块标记为从一开始就可以访问。他们走到最后

我遇到了这个面试问题。第一部分内容如下:

给您的矩阵包含字母“U”、“D”、“L”、“R”和“X”U'允许你向上移动,'L'允许向左移动,等等。'X'是 目的地检查是否有可能从目的地到达目的地 左上角

这一部分很容易用DFS完成。不过,我很难理解第二部分:

您需要进行多少次编辑,例如更改“U”->“L”,以便 到达X


我假设这可以通过修改BFS来完成,BFS计算我们违背指定方向的次数。有人能给点提示吗?

只有一条路径,所以从一开始就迭代它,并将您访问的每个方块标记为从一开始就可以访问。他们走到最后,做同样的事情,向后跑。因为您正在向后运行,所以可能有许多路径,向上和向下都可以通向同一个正方形。无论如何,将这些正方形标记为可从到达终点。如果第一个集合包含与第二个集合相邻的正方形,则需要进行一次编辑。否则,您必须标记分离的方块,并进行距离变换,然后进行特征变换。请参见我的二值图像库。必须对最窄的颈部进行编辑,以将路径从集合1驱动到集合2。

只有一条路径,因此从一开始就迭代它,并将您访问的每个方块标记为从一开始就可以到达。他们走到最后,做同样的事情,向后跑。因为您正在向后运行,所以可能有许多路径,向上和向下都可以通向同一个正方形。无论如何,将这些正方形标记为可从到达终点。如果第一个集合包含与第二个集合相邻的正方形,则需要进行一次编辑。否则,您必须标记分离的方块,并进行距离变换,然后进行特征变换。请参见我的二值图像库。必须编辑最窄的颈部,以驱动从集合1到集合2的路径。

本质上,您需要计算从左上角到矩阵的每个元素,特别是到标记为X的元素的编辑距离,我的意思是,为了能够从左上角到达给定元素,必须在矩阵中进行的编辑次数

为此,您可以首先查找编辑距离为零的所有元素,即左上角和所有可以从其访问的元素。您提到可以使用深度优先搜索,但它甚至不是真正的搜索,因为每个元素都确切地告诉您哪个元素在它之后。所以从左上角只有一条路径,要么在X处结束,要么从边上走下来,要么进入一个循环

然后可以使用广度优先搜索,从刚找到的元素集开始。对于任何给定的d,编辑距离=d+1的元素都是以下元素:

没有编辑距离≤D 以及: 是编辑距离为d的图元的相邻图元 或者可以从这样的邻居那里找到 计算完标记为X的正方形的编辑距离后,可以立即停止


此方法最多访问一次每个元素,因此如果矩阵有N个元素,则此方法在时间和空间上都有效。

本质上,您需要计算从左上角到矩阵每个元素,特别是到标记为X的元素的编辑距离,我的意思是,为了能够从左上角到达给定元素,必须在矩阵中进行的编辑次数

为此,您可以首先查找编辑距离为零的所有元素,即左上角和所有可以从其访问的元素。您提到可以使用深度优先搜索,但它甚至不是真正的搜索,因为每个元素都确切地告诉您哪个元素在它之后。所以从左上角只有一条路径,要么在X处结束,要么从边上走下来,要么进入一个循环

然后可以使用广度优先搜索,从刚找到的元素集开始。对于任何给定的d,编辑距离=d+1的元素都是以下元素:

没有编辑距离≤D 以及: 是编辑距离为d的图元的相邻图元 或者可以从这样的邻居那里找到 计算完标记为X的正方形的编辑距离后,可以立即停止


此方法最多访问一次每个元素,因此如果矩阵有N个元素,则此方法在时间和空间上都是有效的。

矩阵表示一个有向图:节点是矩阵中的位置,有向边由节点中的字母表示

然后,如果图中有一条从左上角到X的路径,那么就有一条从左上角到X的路径。你可以使用Dijkstra的最短路径算法来确定这条路径。您也可以使用DFS,但我们需要Dijkstra 反正在第二部分

要确定使路径成为可能的最小编辑次数,可以将矩阵转化为加权的有向图。在任意两个相邻节点a和b之间,如果a已经包含b的方向,则在a和b之间添加权重为0的加权边,否则添加权重1。权重为0的边表示遵循矩阵中已存在的方向,权重为1的边表示编辑节点


然后,使用Dijkstra算法在图中找到从左上角到X的最小权重路径。此最短路径的权重是所需的编辑次数。

矩阵表示有向图:节点是矩阵中的位置,有向边由节点中的字母表示

然后,如果图中有一条从左上角到X的路径,那么就有一条从左上角到X的路径。你可以使用Dijkstra的最短路径算法来确定这条路径。您也可以使用DFS,但在第二部分中我们仍然需要Dijkstra

要确定使路径成为可能的最小编辑次数,可以将矩阵转化为加权的有向图。在任意两个相邻节点a和b之间,如果a已经包含b的方向,则在a和b之间添加权重为0的加权边,否则添加权重1。权重为0的边表示遵循矩阵中已存在的方向,权重为1的边表示编辑节点



然后,使用Dijkstra算法在图中找到从左上角到X的最小权重路径。此最短路径的权重是所需的编辑次数。

我无法决定是否喜欢此方法。我喜欢认识到这是一个普遍问题的特例,其众所周知的解决方案可以应用;但另一方面,这些众所周知的一般解比这种情况所需要的更复杂。@ruakh你认为你的解比Dijkstra的算法更容易实现吗?对我来说似乎差不多。我想是的,但也许我有偏见-P我的解决方案也有稍微好一点的渐近复杂性,尽管这在实际情况下不太可能产生差异。对我来说,实现好的老dijkstra比从@ruakh定制解决方案更容易。我花了大约20分钟。你不需要从矩阵中构建一个图,你只需要使用矩阵本身,因为你知道谁与谁连接。来自@ruakh的解决方案很好,应该不会更难实现。我认为我的解决方案在实践中可能更容易,因为可能您以前已经实现过Dijkstra。但是,正如ruakh指出的,ruakh的解决方案具有更好的时间复杂度——它是OV而不是OV log V。我无法决定是否喜欢这种方法。我喜欢认识到这是一个普遍问题的特例,其众所周知的解决方案可以应用;但另一方面,这些众所周知的一般解比这种情况所需要的更复杂。@ruakh你认为你的解比Dijkstra的算法更容易实现吗?对我来说似乎差不多。我想是的,但也许我有偏见-P我的解决方案也有稍微好一点的渐近复杂性,尽管这在实际情况下不太可能产生差异。对我来说,实现好的老dijkstra比从@ruakh定制解决方案更容易。我花了大约20分钟。你不需要从矩阵中构建一个图,你只需要使用矩阵本身,因为你知道谁与谁连接。来自@ruakh的解决方案很好,应该不会更难实现。我认为我的解决方案在实践中可能更容易,因为可能您以前已经实现过Dijkstra。但是,正如ruakh所指出的,ruakh的解决方案具有更好的时间复杂性——它是OV而不是OV log V。我认为它会起作用。我无法想象在30分钟内实现它。这似乎是BFS的组合,我们一层一层地进行,在添加了距离为d+1的元素后,我们必须探索其可到达的元素。@damluar:DFS可以只是一个循环,不需要堆栈、递归或其他什么,因为没有元素的outdegree大于1。它将填充编辑距离表。BFS也可以是一个循环,它保持元素的to_进程队列,我们已经设置了edit_距离,但还没有搜索邻居。但是是的,30分钟很紧。我同意这个算法;但是时间和空间的复杂性是在^2上的,就像矩阵一样size@Dolev:OP没有指出这是一个平方矩阵,因此我认为,与其为行数和列数引入单独的变量n和m,不如为元素总数引入n更简单。我认为你不同意?如果N是矩阵的大小,我同意。但是你在我误解的答案中写了数组+1我认为它会起作用。我无法想象在30分钟内实现它。这似乎是一个组合的BFS,我们去一层一层和DFS后添加
使用d+1距离定义元素时,我们必须探索其可到达的元素。@damluar:DFS可以只是一个循环-不需要堆栈、递归或其他什么-因为没有元素的outdegree大于1。它将填充编辑距离表。BFS也可以是一个循环,它保持元素的to_进程队列,我们已经设置了edit_距离,但还没有搜索邻居。但是是的,30分钟很紧。我同意这个算法;但是时间和空间的复杂性是在^2上的,就像矩阵一样size@Dolev:OP没有指出这是一个平方矩阵,因此我认为,与其为行数和列数引入单独的变量n和m,不如为元素总数引入n更简单。我认为你不同意?如果N是矩阵的大小,我同意。但是你在我误解的答案中写了数组+1矩阵中的一个元素包含多个字母合法吗?编辑后是否合法?否。给定的矩阵在一个单元格中只能有一个字符。矩阵中的一个元素包含多个字母是否合法?编辑后是否合法?否。给定的矩阵在一个单元格中只能有一个字符。