BFS
프로그래머스 게임 맵 최단거리 문제를 통해 처음 bfs 를 접해보았다.
bfs 가 무엇인가 맛보고 이해하기에 좋은 문제인것 같다.
dfs 로 풀어보려고 안간 힘을 써봤지만 실패했다.
최단거리 문제는 대표적인 bfs 문제라고 하며, Queue 를 이용한다.
풀이
- 너비 우선 탐색 알고리즘을 이용하여 탐색
- queue 에서 시작 좌표 값(0, 0)을 꺼내서 visited 에 방문 여부 겸 이동 수를 기록 후 사방탐색 시작
- 사방탐색 조건에 의해 사방이 막혔거나 방문한 길 밖에 없는 경우의 수는 걸러지고 남은 경우들은 각자의 최선의 선택으로 탐색
- 사방탐색 후 다음 좌표를 queue 에 저장하고 다음 좌표의 방문 여부 겸 이동 수를 visited 에 기록
- 각자의 최선의 선택으로 탐색한 경우만 남았으므로 가장 먼저 queue 가 비어서 탐색을 진행할 수 없는 경우가 최단거리
- 탐색 종료 후 도착점 좌표에 해당하는 visited 의 값을 반환(0 이면 방문한 적이 없다는 뜻이므로 -1)
최종 코드
import java.util.*;
class Solution {
int n = 0;
int m = 0;
// 사방탐색용 dx, dy
int[] dx = {1, 0, -1, 0};
int[] dy = {0, 1, 0, -1};
// 너비 우선 탐색
public void bfs(int[][] maps, int[][] visited, int x, int y) {
// 방문 여부 겸 이동 수를 해당 시작 좌표에 기록
visited[y][x] = 1;
// queue 초기값 (0, 0)
Queue<int[]> que = new LinkedList<>();
que.add(new int[]{y, x});
// queue 에서 현재 좌표를 꺼내서 사용
// queue 가 비었다는건 더 이상 탐색할 수 없다는 뜻
while (!que.isEmpty()) {
int[] now = que.poll();
y = now[0];
x = now[1];
// 사방탐색 조건
// 1. y, x 가 최대값(n, m)을 넘지 않음
// 2. 방문하지 않은 좌표(visited = 0 인 좌표)
// 3. 해당하는 maps 의 값이 1인 좌표
for (int i = 0; i < 4; i++) {
if (x + dx[i] >= 0 &&
x + dx[i] < m &&
y + dy[i] >= 0 &&
y + dy[i] < n &&
visited[y + dy[i]][x + dx[i]] == 0 &&
maps[y + dy[i]][x + dx[i]] == 1) {
// 탐색 조건에 만족할 시 다음 좌표에 방문 여부 겸 이동 수를 기록
visited[y + dy[i]][x + dx[i]] = visited[y][x] + 1;
// 다음 좌표를 queue 에 추가
que.add(new int[]{y + dy[i], x + dx[i]});
}
}
}
}
public int solution(int[][] maps) {
n = maps.length;
m = maps[0].length;
int[][] visited = new int[n][m];
// 너비 우선 탐색 시작
// 초기값 (0, 0) 설정
bfs(maps, visited, 0, 0);
// 도착점(visited) 의 값을 확인
// 0 이면 방문한 적이 없으므로 -1
// 0 이 아니면 visited 의 해당 값이 이동 수를 의미
return visited[n -1][m -1] == 0 ? -1 : visited[n -1][m -1];
}
}
'알고리즘 > DFS 및 BFS' 카테고리의 다른 글
[알고리즘] 단어 변환(JAVA) (0) | 2023.11.14 |
---|---|
[알고리즘] DFS 입문(JAVA) (0) | 2023.10.15 |