迷宫问题,定义一个二维数组 N*M ,如 5 × 5 数组下所示:
maze=[
[0,1,0,0,0],
[0,1,1,1,0],
[0,0,0,0,0],
[0,0,0,0,0],
[0,1,1,1,0]
]
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路
解题思路1,使用深度优先查找,即一条路走到黑,使用栈来存储坐标,能走通的放入栈中并标记,如遇到没有路了,就把栈顶出栈,再寻找此坐标还有没有其他可以走的路
#maze表示迷宫
maze=[
[0,1,0,0,0],
[0,1,1,1,0],
[0,0,0,0,0],
[0,0,0,0,0],
[0,1,1,1,0]
]
#表示向四个方向移动坐标
dirs=[
lambda x,y:(x+1,y),
lambda x,y:(x-1,y),
lambda x,y:(x,y+1),
lambda x,y:(x,y-1)
]
def stack_path(x1,y1,x2,y2):
#x1,y1:初始坐标;x2,y2:表示终点坐标
stack=[] #建一个空列表,当做一个栈
stack.append((x1,y1)) #将初始坐标存起来
while(len(stack)>0): #栈内有元素就循环
curNode=stack[-1] #取当前坐标
if curNode[0]==x2 and curNode[1]==y2: #当前坐标等于终点坐标,路径找到,结束程序
for p in stack:
print("(%d,%d)" % (p[0],p[1]))
return True
for dir in dirs: #遍历四个方向
nexNode=dir(curNode[0],curNode[1])
if 0<= nexNode[0]<=x2 and 0<= nexNode[1]<= y2: #坐标没有越界
if maze[nexNode[0]][nexNode[1]] == 0:
stack.append(nexNode) #坐标等于0,就把他放入栈中,并标记为2
maze[nexNode[0]][nexNode[1]] = 2
break
else: #坐标越界了,进入下轮循环,看其他方向
continue
else: #如果没有路可以走,回退,将当前节点出栈,如果for循环正常结束,else中语句执行。如果是break的,则不执行。
stack.pop()
else:
return False
stack_path(0,0,4,4)
解题思路2:广度优先,同时找多条路,找到路径最短的那条路。使用队列保存当前在走的多个坐标,走过的从左边出队列。然后还需要一个记录所有走过的坐标和该坐标的上一个坐标的下标
from collections import deque
maze=[
[0,1,0,0,0],
[0,0,0,1,0],
[0,1,0,1,0],
[0,1,0,0,0],
[0,0,0,1,0]
]
dirs=[
lambda x,y:(x+1,y),
lambda x,y:(x-1,y),
lambda x,y:(x,y+1),
lambda x,y:(x,y-1)
]
def print_r(path):
#print(print_r)
curNode=path[-1]
real_p=[]
while curNode[2]!=-1:
real_p.append((curNode[0],curNode[1]))
curNode=path[curNode[2]]
real_p.append((curNode[0],curNode[1]))
real_p.reverse()
for p in real_p:
print(p)
def maze_path_queue(x1,y1,x2,y2):
queue=deque()
queue.append((x1,y1,-1))
path=[]
while len(queue)>0:
curNode=queue.popleft()
path.append(curNode)
if curNode[0]==x2 and curNode[1]==y2:
print_r(path)
return True
for dir in dirs:
nexNode=dir(curNode[0],curNode[1])
#print(nexNode)
if 0<= nexNode[0]<=x2 and 0<= nexNode[1]<= y2:
if maze[nexNode[0]][nexNode[1]]==0:
queue.append((nexNode[0],nexNode[1],len(path)-1))
maze[nexNode[0]][nexNode[1]]=2
else:
continue
else:
return False
maze_path_queue(0,0,4,4)