Algorithm
[프로그래머스] 게임 맵 최단거리
채햔
2023. 2. 12. 22:13
DFS와 BFS에 관련된 문제이다.
DFS는 전체를 경험하여 그 중 원하는 값을 포착하는 것
BFS는 경험하는 도중 원하는 값이 발견되면 바로 종료 가능
* 최단거리를 구할 때는 BFS다 !!
내 코드) 틀림!
function solution(maps) {
answer = 0;
let m = maps.length;
let n = maps[0].length;
function getAnswer(x, y, val, list) {
while (y < m && x < n) {
if (y === m - 1 && x === n - 1) {
answer = answer > val ? val : answer;
}
if (x < n - 1 && list[y][x + 1] == 1) {
list[y][x + 1] = 0;
getAnswer(x + 1, y, val + 1, list);
}
if (x >= 1 && list[y][x - 1] == 1) {
list[y][x - 1] = 0;
getAnswer(x - 1, y, val + 1, list);
}
if (y < m - 1 && list[y + 1][x] == 1) {
list[y + 1][x] = 0;
getAnswer(x, y + 1, val + 1, list);
}
if (y >= 1 && list[y - 1][x] == 1) {
list[y - 1][x] = 0;
getAnswer(x, y - 1, val + 1, list);
}
}
}
getAnswer(0, 0, 0, maps);
return answer === 0 ? -1 : answer;
}
내 코드의 오류)
모든 경로를 다 확인하고, 가장 길이가 짧았던 것을 선정하는 DFS방식으로 문제를 풀었기 때문에, 너무 많은 시간이 걸렸을 뿐 아니라, 코드 오류로 인하여 답안이 맞지 않았다.
다른 분들이 푸신 답안 코드이다.
function solution(maps) {
var yLen = maps.length - 1;
var xLen = maps[0].length - 1;
var queue = [[0, 0]];
var visited = Array.from(new Array(maps.length), () =>
new Array(maps[0].length).fill(false)
); //false로 가득 찬 maps와 동일하게 생긴 list
var result = 0;
while (queue.length) {
//queue가 0이 아닐 때까지 반복
// 모두 방문했던 곳이면 자동으로 끝
result++;
var size = queue.length;
for (var i = 0; i < size; i++) {
var point = queue.shift(); //queue의 가장 앞에 것 꺼냄
var curY = point[0];
var curX = point[1];
if (visited[curY][curX]) continue; // 방문했던 곳이면 넘어감
maps[curY][curX] = 0; //방문할 곳 0으로 변경
visited[curY][curX] = true; //방문했다고 표시
if (curY === yLen && curX === xLen) return result; // 적진에 도착
if (curY < yLen && maps[curY + 1][curX] === 1) //남쪽
queue.push([curY + 1, curX]);
if (curX < xLen && maps[curY][curX + 1] === 1)
queue.push([curY, curX + 1]); //동쪽
if (curY > 0 && maps[curY - 1][curX] === 1) // 서쪽
queue.push([curY - 1, curX]);
if (curX > 0 && maps[curY][curX - 1] === 1) //북쪽
queue.push([curY, curX - 1]);
}
}
return -1;
}
의문점)
queue가 빈 값이 될때까지 while문을 반복해야 한다.
모든 조건을 확인하고, 참이면 queue에 push 하면 결국 가장 긴 루트까지 확인해야 끝나는 것 아닌가라는 의문이 생겼다.
해결)
while문 반복 조건은 끝까지 확인했어도 적진(5,5)에 도착하지 못했을 경우를 대비한 것이다.
while문 속에 적진에 도착했을 때 return 하는 if문이 있기 때문에 가장 짧은 경우에서 중단될 수 있다.
갈래길이 나올 때, 오른쪽 그림이 왼쪽 그림보다 먼저 적진에 도착하고, 도착했을 때의 이동횟수를 return한다.
즉, 파란색 경로가 오른쪽 위에 있을 때, 빨간색 경로가 적진에 도달했기 때문에 해당 값이 return된다.