迷宫问题
迷宫问题是面试问题中常见的问题,下面我给出迷宫的几种形式
可以分为多出口和单出口,不带环和带环
迷宫解题方法
给出三种标记的方法,两种思路
首先说标记方法,标记方法很重要,关乎问题解决的方便程度
标记方法一
将走过的路标记为任意规定的相同数字,比如全部标记为2,区别于一开始的1即可,规则是碰到2不可走,因为其已走过,这种方法的缺点:经常会漏解线路,且带环问题无法解决
标记方法二
标记方法同法一,不同的是规则,退回的时候将标记置回1,这种标记方法比法一更好,但是使用方法较苛刻,只能使用递归方法求解,且可以求出最短路径,缺点会走很多冤枉路,降低算法效率
标记方法三(最好的方法)
将入口标记为2,以后每走一步标记为前一步标记 + 1,退回时不处理标记,规则是只有小于标记的路可以走,大于后面标记则不可走,比如3碰到5,可以走,但是5碰到3,不可走,这样可以避免走较远的路,从而方便找寻最短路径,坏处是可能无法将所有的路走遍(这个未走的路必定是较长的路径),一般求解都是求最短路径,最长路径是否求出无伤大雅
思路一
栈解决
利用栈将走过的路压栈,上下左右搜索,有路可走便入栈,直至无路可走,退栈返回,当退栈到分岔路口,继续搜索未搜索的路,下面附上简化的代码思路,这个思路只写思路,不写代码,因为这种思路并不好,我主要写思路二
Stack* s;
StackPush(s, entry);//先入迷宫入口
while (StackEmpty(s))//只有栈为空说明无路可走,已经回到起点
{
cur = StackTop(s);//获取当前点位
首先标记当前点位,可以使用法1,防止重复走;
if (判断是否走到出口或无路可走)
{
StackPop(s);//出栈,返回上一步
}
if (上可以走)
{
走上;
将当前点入栈;
continue;
}
if (下可以走)
{
走下;
将当前点入栈;
continue;
}
if (左可以走)
{
走左;
将当前点入栈;
continue;
}
if (右可以走)
{
走右;
将当前点入栈;
continue;
}
}
思路二
使用递归来解决
其实递归的原理和栈是一样的,但是递归天然可以走遍所有入口,比栈更灵活,递归的原理可以理解为栈帧的不断创建,在这个过程中栈帧不断创建,当走到头时,栈帧释放,相当于不断地压栈出栈,且不需要自行写栈来辅助(不理解栈帧的可以看我之前写的栈帧的博客)
我在获取最短路径的时候用栈辅助来获取,递归时并未使用栈