題目:給一個二維列表,表示迷宮(0表示通道,1表示圍牆)。給出算法,求一條走出迷宮的路徑。
maze = [ [1,1,1,1,1,1,1,1,1,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,0,0,1,1,0,0,1], [1,0,1,1,1,0,0,0,0,1], [1,0,0,0,1,0,0,0,0,1], [1,0,1,0,0,0,1,0,0,1], [1,0,1,1,1,0,1,1,0,1], [1,1,0,0,0,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1] ]

解決思路:
- 在一個迷宮節點(x,y)上,可以進行四個方向的探查:maze[x-1][y], maze[x+1][y], maze[x][y-1], maze[x][y+1]
- 思路:從一個節點開始,任意找下一個能走的點,當找不到能走的點時,退回上一個點尋找是否有其他方向的點。
- 方法:創建一個空棧,首先將入口位置進棧。當棧不空時循環:獲取棧頂元素,尋找下一個可走的相鄰方塊,如果找不到可走的相鄰方塊,說明當前位置是死胡同,進行回溯(就是講當前位置出棧,看前面的點是否還有別的出路)
用棧實現:
maze = [ [1,1,1,1,1,1,1,1,1,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,0,0,1,1,0,0,1], [1,0,1,1,1,0,0,0,0,1], [1,0,0,0,1,0,0,0,0,1], [1,0,1,0,0,0,1,0,0,1], [1,0,1,1,1,0,1,1,0,1], [1,1,0,0,0,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1] ] dirs = [ lambda x,y:(x-1,y), #上 lambda x,y:(x,y+1), #右 lambda x,y:(x+1,y), #下 lambda x,y:(x,y-1), #左 ] def solve_maze(x1, y1, x2, y2): stack = [] stack.append((x1,y1)) maze[x1][y1] = 2 while len(stack) > 0: # 當棧不空循環 cur_node = stack[-1] if cur_node == (x2,y2): #到達終點 for p in stack: print(p) return True for dir in dirs: next_node = dir(*cur_node) if maze[next_node[0]][next_node[1]] == 0: #找到一個能走的方向 stack.append(next_node) maze[next_node[0]][next_node[1]] = 2 # 2表示已經走過的點 break else: #如果一個方向也找不到 stack.pop() else: print("無路可走") return False
用隊列實現:
解決思路:
- 思路:從一個節點開始,尋找所有下面能繼續走的點。繼續尋找,直到找到出口。
- 方法:創建一個空隊列,將起點位置進隊。在隊列不為空時循環:出隊一次。如果當前位置為出口,則結束算法;否則找出當前方塊的4個相鄰方塊中可走的方塊,全部進隊。

from collections import deque maze = [ [1,1,1,1,1,1,1,1,1,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,1,0,0,0,1,0,1], [1,0,0,0,0,1,1,0,0,1], [1,0,1,1,1,0,0,0,0,1], [1,0,0,0,1,0,0,0,0,1], [1,0,1,0,0,0,1,0,0,1], [1,0,1,1,1,0,1,1,0,1], [1,1,0,0,0,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1] ] def solve_maze2(x1,y1,x2,y2): queue = deque() path = [] # 記錄出隊之后的節點 queue.append((x1,y1,-1)) maze[x1][y1] = 2 while len(queue) > 0: cur_node = queue.popleft() path.append(cur_node) if cur_node[0] == x2 and cur_node[1] == y2: #到終點 real_path = [] x,y,i = path[-1] real_path.append((x,y)) while i >= 0: node = path[i] real_path.append(node[0:2]) i = node[2] real_path.reverse() for p in real_path: print(p) return True for dir in dirs: next_node = dir(cur_node[0], cur_node[1]) if maze[next_node[0]][next_node[1]] == 0: queue.append((next_node[0], next_node[1], len(path)-1)) maze[next_node[0]][next_node[1]] = 2 # 標記為已經走過 else: print("無路可走") return False solve_maze2(1,1,8,8)
