在2d数组中查找最近的可访问数字

时间:2013-04-28 15:23:03

标签: java algorithm

我有一个包含数字的二维数组。它可能是这样的:

11211
1  31
1 111
1  11
13111

数字1是"墙",2是入口,3是我们想要到达的点。正如你所看到的,我们有两次出现3次,并且他们并不是同样接近。我需要找到最近的一个。请记住,输入数组是随机的,不必看起来像这样。

我正在思考如何解决它的问题: 先找到入口。这只能在O(n ^ 2)(最差情况)时间内完成,因为入口可能在阵列中的任何位置,并且不必沿着边缘。我可以毫无问题地实现这一点。

然后我需要从阵列中的入口点进行搜索。每当我找到3号时,我都需要记住我访问它,以及点之间的距离(示例中的2和3)。让我们说我发现离入口最远的3号。这显然不是最接近的一点(如果我们看一下这个例子)。我需要跳回入口再次搜索。我想过要有一个实时计数器,计算步数,这样如果我做的步骤比我刚发现的宝贝更多,我会停下来说,之前发现的宝藏是最接近的。

我认为有一种更好的方法可以有效地实现它,但我真的无法想到如何做到这一点。我试着搜索Dijkstra的算法,但它似乎找到了从入口到阵列中所有数字的最短路径(数字是目标数字3)。我想你可以过滤掉它们中最短的一个,但你究竟会用Java实现这个呢?

我不是在寻找完整的代码,只是为了指导我,所以我可以理解如何实现它。

2 个答案:

答案 0 :(得分:4)

假设“距离”是指在空旷的地方行走。

  1. 从入口开始,将元素向左,向上,向下和向右移动,如果已经标记为已访问,则不要进入该元素。如果您看到墙壁或撞到边缘,请将其标记为已访问并忽略它。如果您看到一个空格,请将该元素放入队列中。

  2. 标记出访的入口。

  3. 从(1)

  4. 中的队列中取出元素
  5. 将出队的元素用作新的“入口”,重复(1) - (3)直到你点击3,在这种情况下,停止。 3最接近入口

  6. 如果您没有遇到任何3并且您已经在(1)中获得了所有访问过的内容,则表示从入口处无法访问3

    < / LI>

    这是Breadth First Search的一个实例,并使用类似于Flood fill.

    的技术

    此外,当且仅当有多个3具有相同且最短的距离时,您在(1)中访问的方向可能会影响最终结果。

答案 1 :(得分:1)

我喜欢Bellman ford这样的问题。当然它的N ^ 3(在这种情况下),但它实现起来非常简单。

http://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm

在你的情况下:

<强>设置    创建一个2D数组ShortestDistance并用无穷大填充它。    遍历数组并将ShortestDistance设置为0,其中有一扇门。这些是我们可以在0距离内到达的网格点。

<强>算法

   For itr in 0 to N // (Max Distance between any door and 
      For i in 0 to N // row index
         For j in 0 to N //column number
           If Grid[i][j] == 1
              Continue; //its a wall and it can't propagate shortest distance
           else 
               ShortestDistance[i][j] = min(
                                           ShortestDistance[i][j],  //current value
                                           1 + (ShortestDistance among all neighbours*) //reduced shortest path.

*在每个步骤中,我们通过到达其邻居之一的最短距离+ 1或当前值本身来更新到达地点的最短距离。

后期处理 浏览ShortestDistance 2D数组并打印对应于'3'类型点的最小值。