从点 (0,0) 到 (X,Y) 的通路
一个 的矩阵,机器人只能往右走或者往下走,从点 到点 ,一共有多少种通路呢?
增加一点难度,假设有些点是不能走的,那么应该如何设计算法来找到一条可能的通路呢?
第一个问题其实很简单,就是从 这么多步数中选择 步往右走,即
如果找到这条通路呢?其实有没有不可走的点,差距不是很大,就是在判断往哪个方向走的时候增加一个条件判断就好了。还有一个大一点的区别,就是某些点不能走,导致从 点无法到达一部分点。
现在我们分析一下思路,怎么走到点 呢?如果到了 或者是 ,那么再走一步就能到 了。问题变成了,找到一条到达 或 的路径。
如何到 呢?再往前想一步,找一条到 或者是 的路径即可。
如何到 呢?那么先找到一条到 或者是(X-2,Y)的路径即可。
总体来说,就是一个递归算法。
仔细想一下,上述的递归算法,都需要计算到 点的路径,那么,我们可以考虑把这个结果缓存起来,第二次使用的时候,就不用再次递归计算了。
具体到这个题目,只需要缓存从 能否到点 即可。
struct Point
{
public Point(int x, int y)
{
X = x;
Y = y;
}
public int X { get; set; }
public int Y { get; set; }
}
static bool GetPath(int x, int y, List<Point> path, Dictionary<Point, bool> cache)
{
Point point = new Point(x, y);
if (cache.ContainsKey(point))
{
// Already visited this cell
return cache[point];
}
if (x == 0 && y == 0)
{
// found a path
return true;
}
bool success = false;
// Try left
if (x >= 1 && IsFree(x - 1, y))
{
success = GetPath(x - 1, y, path, cache);
}
// Try up
if (!success && y >= 1 && IsFree(x, y - 1))
{
success = GetPath(x, y - 1, path, cache);
}
if (success)
{
// Right way! Add to path
path.Add(point);
}
// Cache result
cache.Add(point, success);
return success;
}
private static bool IsFree(int x, int y)
{
return !(x == 0 && y == 1
|| x == 0 && y == 2
|| x == 1 && y == 2
|| x == 2 && y == 2);
}