[プログラマーアルゴリズム]ゲームマップ最短距離
28349 ワード
質問する
ゲームマップ最短距離
に近づく
問題の説明を読むと、探求問題であることがわかります.しかし,これは単純な探索ではなく,最短距離を求める探索であるため,dfsではなくbfsで解くことができる.始点から、上下左右を見るたびに、これまで見たことも壁でもない場所が見つかった場合は、キューに位置情報を含め、次の場所をブラウズし続けます.
探索したタグをcheck配列に配置して管理し、その位置にアクセスしてキューに入れるのではなくcheck値を発見したときに適用してこそ、効率スコアが得られます.訪問時にチェックすると、訪問前に何度も同じ場所をチェックしますから.こちらはよく説明されています.
コード#コード#
def solution(maps):
n = len(maps)
m = len(maps[0])
#방문 여부 확인하는 배열
check = [[False for i in range(m)] for j in range(n)]
check[0][0]= True
#bfs용 스택
s=[]
s.append((0,0,1)) #row,col,distance
while s:
current = s.pop(0)
row = current[0]
col = current[1]
dist = current[2]
#상대팀 진영 도착
if row==n-1 and col==m-1:
return dist
nextRow = [row+1,row-1,row,row]
nextCol = [col,col,col-1,col+1]
for i in range(4):
if nextRow[i]<0 or nextRow[i]>=n or nextCol[i]<0 or nextCol[i]>=m:
continue
elif check[nextRow[i]][nextCol[i]]==False and maps[nextRow[i]][nextCol[i]]==1:
check[nextRow[i]][nextCol[i]] = True
s.append((nextRow[i],nextCol[i],dist+1))
return -1
改善された回答
上記のコードは、すべてのテスト例を通過することもできますが、効率を向上させるために、コードを改善しました.
Pythonでは,リストのpop演算には通常O(n)の時間的複雑さが必要である.したがって,リストの代わりに,両端値に近づくとO(1)時間の複雑さを持つdequeが用いられる.
from collections import deque
def solution(maps):
n = len(maps)
m = len(maps[0])
#방문 여부 확인하는 배열
check = [[False for i in range(m)] for j in range(n)]
check[0][0]= True
#bfs용 큐
s=deque()
s.appendleft((0,0,1)) #row,col,distance
while s:
current = s.pop()
row = current[0]
col = current[1]
dist = current[2]
#상대팀 진영 도착
if row==n-1 and col==m-1:
return dist
nextRow = [row+1,row-1,row,row]
nextCol = [col,col,col-1,col+1]
for i in range(4):
if nextRow[i]<0 or nextRow[i]>=n or nextCol[i]<0 or nextCol[i]>=m:
continue
elif check[nextRow[i]][nextCol[i]]==False and maps[nextRow[i]][nextCol[i]]==1:
check[nextRow[i]][nextCol[i]] = True
s.appendleft((nextRow[i],nextCol[i],dist+1))
#print(s)
return -1
リストを使用した結果
Dequeを使用した結果
あまり差はありませんが、dequeの速度が速いことが細かくわかります.
改善された解答2
check配列を単独で生成して管理するのはすでにアクセスした場所では効率的ではないので,checkのないチェック方法を考えた.どうせ地図は数字0と1で埋められていて、0は壁で、1は長さです.したがって,アクセスのたびにmapsの値に1を足すと,1ではなく0(壁を塞ぐ)か,すでにアクセスした場所が分かる.check配列の代わりにこの方法を用いることができる.
from collections import deque
def solution(maps):
n = len(maps)
m = len(maps[0])
#bfs용 큐
s=deque()
s.appendleft((0,0,1)) #row,col,distance
while s:
current = s.pop()
row = current[0]
col = current[1]
dist = current[2]
#상대팀 진영 도착
if row==n-1 and col==m-1:
return dist
nextRow = [row+1,row-1,row,row]
nextCol = [col,col,col-1,col+1]
for i in range(4):
if nextRow[i]<0 or nextRow[i]>=n or nextCol[i]<0 or nextCol[i]>=m:
continue
elif maps[nextRow[i]][nextCol[i]]==1:
maps[nextRow[i]][nextCol[i]]+=1
s.appendleft((nextRow[i],nextCol[i],dist+1))
return -1
print(solution([[1,0,1,1,1],[1,0,1,0,1],[1,0,1,1,1],[1,1,1,0,1]]))
print(solution([[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1]]))
print(solution([[1,1,1],[1,1,1],[1,1,1]])
check配列を単独で生成することに比べて,時間は確かに減少した.
Reference
この問題について([プログラマーアルゴリズム]ゲームマップ最短距離), 我々は、より多くの情報をここで見つけました https://velog.io/@syhwang4223/프로그래머스-알고리즘-게임-맵-최단거리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol