迷宫问题多数解法都是使用递归,但递归对于算法还是有要求的,如果
时间复杂度不是O(log n)那么还是不建议使用
因为当问题规模较大时,每次递归无法将规模指数级缩减
那么总递归次数就会很多,会有爆栈的风险
例如
def fn(x):
if x == 1:
return 1
return fn(x - 1) * x
fn(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in fn
File "<stdin>", line 4, in fn
File "<stdin>", line 4, in fn
[Previous line repeated 995 more times]
File "<stdin>", line 2, in fn
RecursionError: maximum recursion depth exceeded in comparison
所以,能用循环解决的还是用循环吧
迷宫问题的使用循环的解法
# 设置一个迷宫,1代表可走,0代表不可走
mig = [
[0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 1, 1, 0],
[0, 1, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0]
]
mig2 = [
[0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 1, 0],
[0, 1, 1, 0, 0, 1, 0],
[0, 0, 1, 1, 1, 1, 0],
]
# 设置起点终点标志
blogo, elogo = 'B', 'E'
# 方向提示
types = {(1, 0): '↓', (0, 1): '→', (-1, 0): '↑', (0, -1): '←'}
# 传递一个二维数组(列表)及起点和终点的下标位置
def wayFinding(s: list[list[bool]], begin: tuple[int, int], end: tuple[int, int]):
ex, ey = end
bx, by = begin
# 将起点设为开始的标志
s[bx][by] = blogo
# 开始寻路,当终点元素被更改时结束
while s[ex][ey] == 1:
# 如果只根据起点和终点的坐标来确定整个路程的方向优先级过于绝对,所
# 以将它放在循环中
# 根据当前下标位置动态更改优先级
x, y = bx - ex, by - ey
d = {(1, 0): x, (0, 1): y, (-1, 0): -x, (0, -1): -y}
list_ = sorted(list(d.keys()), key=lambda k: d[k])
# 根据方向优先级寻路
for i, j in list_:
# 判断要走的位置是否可走,若不为1则代表不可走或已走过,换下一个方向
try:
if s[bx + i][by + j] == 1:
bx += i
by += j
s[bx][by] = types.get((i, j))
break
except IndexError:
# 可能会出现索引越界,当做不可走的情况跳过就好
continue
else:
# 如果for循环正常结束那就代表四个方向均已走不通或已走过,
# 代表已进入死路,退回起点重新寻路
s[bx][by] = '×'
bx, by = begin
# 到达终点将终点元素设置结束标志
s[ex][ey] = elogo
def toMatrix(s: list[list]):
res = ''
for row in s:
a = ''
for x in row:
a += str(x) + ' '
res += a + '\n'
return res
wayFinding(mig, (1, 1), (6, 1))
wayFinding(mig2, (1, 1), (1, 5))
print(toMatrix(mig))
print(toMatrix(mig2))