문제 파악
게임 맵 최단거리 문제는 깊이/너비 우선 탐색(DFS/BFS) 카테고리에 해당되며 최단거리를 구해야 하므로 BFS(Breadth First Search) 방식으로 해결 할 수 있었다.
우선 BFS란 너비 우선 탐색으로 대표적인 그래프 탐색 방법 중 하나이다. 정점의 자식들을 먼저 탐색하는 방식인 DFS와 다르게 정점들과 같은 레벨에 있는 노드들을 먼저 탐색하는 방식이다.
루트(root)와 가까운 노드들 부터 탐색하기 때문에 최단거리를 구할 때 유용하다. 추가적인 특징으로 두 가지의 큐(Queue)를 사용해야하며 DFS 방식보다 메모리가 많이 사용된다.
풀이 과정
1. 현 지점에서 다음 차례에 갈 수 있는 지점을 리턴하는 함수 만들기
다음의 경우를 제외한 좌표값을 반환하도록 만들었다.
- 이미 지나온 지점
- 갈 수 없는 지점
- 맵을 벗어나는 지점
2. 두 가지 Queue를 이용하여 지나온 지점과 다음 차례에 갈 지점들을 계산
tmpQue에 인접한 노드의 좌표들을 저장하며 tmpQue의 길이가 0이 될 때까지 반복문(while)을 돌렸다.
또한 매 루프마다 history라는 Object에 [0, 0] 부터 시작하여 지나온 지점들을 계층 레벨에 따라 정리하였다.
결국 도달가능한 모든 지점을 순회하다보면 최종 도착 지점의 좌표가 등장하거나 tmpQue의 길이가 0이되어(경로 없음) 반복문이 끝날 것이다.
최종 코드
const direction = [[1,0], [0,-1], [-1,0], [0,1]]
function searchPossiblePosition(nowP, beforeP, maps, n, m) {
var possible = [];
if(nowP[0] === 0 && nowP[1] === 0){
var exceptDirection = [0, 0]
} else {
var exceptDirection = [beforeP[0] - nowP[0], beforeP[1] - nowP[1]];
}
direction.forEach((value) => {
if(value[0] !== exceptDirection[0] || value[1] !== exceptDirection[1]){
var tmp = [nowP[0] + value[0], nowP[1] + value[1]]
if(tmp[0] >= 0 && tmp[1] >= 0 && tmp[0] < n && tmp[1] < m){
if(maps[tmp[0]][tmp[1]] === 1 && tmp[0] >= 0 && tmp[1] >= 0){
possible.push(tmp)
}
}
}
})
return possible
}
function solution(maps) {
var answer = 0;
var debth = 0;
var beforeP = [0, 0];
var visitedQue = [[0, 0]];
var tmpQue = [[0, 0]];
var history = {
'1' : [[0, 0]],
}
var isRepeat = 1
var isArrived = 0
const n = maps.length
const m = maps[0].length
while(!isArrived){
debth++;
history[debth+1] = []
history[debth].forEach((tmp) => {
searchPossiblePosition(tmp, beforeP, maps, n, m).forEach((value) => {
tmpQue.forEach((v) => {
if(v[0] === value[0] && v[1] === value[1]) {
isRepeat = 0
}
})
if(isRepeat){
tmpQue.push(value)
history[debth+1].push(value)
visitedQue.push(value)
}
isRepeat = 1
maps[tmp[0]][tmp[1]] = 2
if(value[0] === n - 1 && value[1] === m - 1){
isArrived = 1
}
})
tmpQue.shift()
})
if(tmpQue.length === 0){
isArrived = -1
} else {
beforeP = tmpQue[0]
}
}
if(isArrived === 1){
answer = debth + 1;
} else {
answer = -1
}
return answer;
}
후기
문제를 풀고 난 뒤 다른 사람들의 풀이를 볼 수 있었는데, 나의 풀이가 많이 부족하다는 것을 다시 한번 알게 되었다. 다른 DFS, BFS 와 관련된 문제들을 더 풀어보며 연습해야겠다.
'코딩 테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 체육복 - 자바스크립트(JavaScript) (2) | 2022.09.30 |
---|---|
[프로그래머스] 타겟 넘버 - 자바스크립트(JavaScript) (0) | 2022.07.25 |