일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 달빛캠퍼스
- 인플레이션에서 살아남기
- Algorithm
- 달빛클럽
- JPA
- programmers
- 노마드코더 강의
- SoftwareExpertAcademy
- ReactJS로 영화 웹 서비스 만들기
- 달빛클럽1기
- 달빛클럽 1기
- Stack
- 경제공부
- 알고리즘
- BOJ
- React.js
- 리액트
- HashMap
- 자바
- SWEA
- React
- 완전탐색
- dfs
- 노마드코더
- 백준
- Java
- 프로그래머스
- 재귀
- 카카오블라인드코딩테스트
- Array
- Today
- Total
th42500의 TIL
[Java] 깊이/너비 우선 탐색(DFS/BFS) - 게임 맵 최단거리 (Lv2) 본문
https://school.programmers.co.kr/learn/courses/30/lessons/1844
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
✔ 입출력 예시
💡 포인트
1️⃣ 최단거리를 구해야 하므로 BFS 알고리즘 활용
https://ichijeochi.tistory.com/43?category=1012068
BFS (Breadth-First Search)
BFS (Breadth-First Search) 그래프 탐색 알고리즘 탐색(Search)이란 많은 양의 데이터 내에서 원하는 데이터를 찾는 과정을 의미 BFS 그래프에서 부모 노드를 먼저 방문한 후, 방문했던 부모 노드의 자식
ichijeochi.tistory.com
2️⃣ 현재 위치에서 갈 수 있는 곳을 탐색하기 위해 사방 탐색 진행 (배열 dr, dc 참고)
3️⃣ 도착하지 못하는 경우에는 -1 반환
❓ 풀이방법
1️⃣ BFS 함수에 필요한 변수들 넣기 (maps, 방문 배열 생성)
2️⃣ 해당 위치의 정보를 담을 class 생성(행 인덱스, 열 인덱스, 현재까지 지나온 칸의 수) & BFS 실행을 위한 Queue 생성
3️⃣ 처음 위치 정보 Queue에 담고 방문 배열에 방문 표시
4️⃣ Queue가 빌 때까지 반복문을 반복
5️⃣ Queue의 가장 첫 원소를 빼내어 해당 위치에서 전진할 수 있는 칸이 있는지 판별 후, 있다면 전진할 수 있는 칸의 정보
Queue에 담기 👉 (새로운 칸의 행, 새로운 칸의 열, 이전 칸의 cnt + 1)
이때, 전진할 수 있는 칸이 있는지 판별할 때는 반드시 새로운 행과 열의 인덱스들이 maps내에서 갈 수 있는 칸인지
판별 후, 방문 여부 등을 판별해야 ArrayIndexOutOfBoundsException 발생 ❌
6️⃣ 반복문 진행 중 현재 뽑은 원소의 행과 열이 도착 지점과 같다면 정답변수에 현재 원소의 칸(cnt)의 값을 담기
7️⃣ 만약, 반복문이 종료되어도 도착지점에 도착하지 못했다면 -1 반환
✔ 소스코드
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class Solution { // 게임 맵 최단거리
public static void main(String[] args) {
// int[][] maps = {{1,0,1,1,1}, {1,0,1,0,1}, {1,0,1,1,1}, {1,1,1,0,1}, {0,0,0,0,1}};
int[][] maps = {{1,0,1,1,1}, {1,0,1,0,1}, {1,0,1,1,1}, {1,1,1,0,0}, {0,0,0,0,1}};
System.out.println(solution(maps));
}
private static int solution(int[][] maps) {
// 1. 최단거리를 구하기 위해 BFS 활용
return bfs(maps, new boolean[maps.length][maps[0].length]);
}
static class Spot { // Q에 담을 원소의 정보
int x; // 행 인덱스
int y; // 열 인덱스
int cnt; // 현재 위치까지 지나온 칸의 수
public Spot(int x, int y, int cnt) {
this.x = x;
this.y = y;
this.cnt = cnt;
}
}
private static int bfs(int[][] maps, boolean[][] v) {
boolean flag = false; // 도착하지 못하는 경우를 위한 flag
int answer = 0; // 정답변수
int[] dr = {-1, 1, 0, 0}; // 행인덱스 이동배열(상 하 좌 우)
int[] dc = {0, 0, -1, 1}; // 열인덱스 이동배열(상 하 좌 우)
// 2. BFS를 실행하기 위한 Queue 생성
Queue<Spot> q = new LinkedList<>();
// 3. 처음 위치의 인덱스 q에 삽입
q.add(new Spot(0, 0, 1));
// 3. 처음 위치 방문한 것으로 표시
v[0][0] = true;
while(!q.isEmpty()) { // 4. q의 원소가 모두 없어질 때까지 반복
Spot s = q.poll();
// 6. q가 비어있지 않아도 목표위치에 도착했다면 해당 위치까지 지나온 칸의 개수 정답변수에 넣고 반복문 멈춤
if(s.x == maps.length-1 && s.y == maps[0].length-1) {
answer = s.cnt;
flag = true; // 도착했으므로 flag 변수 변경
break;
}
for(int i=0; i<dr.length; i++) {
int nr = s.x + dr[i];
int nc = s.y + dc[i];
if(0 <= nr && nr < maps.length && 0 <= nc && nc < maps[0].length && !v[nr][nc] && maps[nr][nc] == 1) {
// 5. 전진할 수 있는 칸이 있다면 q에 담기
q.add(new Spot(nr, nc, s.cnt+1));
v[nr][nc] = true; // 5. 방문한 것으로 처리
}
}
}
if(!flag) { // 7. 방문하지 못했다면
return -1;
}
return answer;
}
}
❗ 결과
👉 테스트 통과
SSAFY때, 알고리즘 스터디를 진행하며 최단거리문제들을 대부분 BFS로 해결했던 것이 기억나 바로 BFS로 문제를 풀었다.
코드 제출 후 효율성 테스트까지 있는 것을 보고 DFS로 풀었다면 시간초과가 떠 문제를 다시 풀어야 하지 않았을까 하는 생각이...
오랜만에 도전한 BFS는 전보다는 오래걸렸지만 한번에 테스트를 통과할 수 있었던 문제였다 😁👍
'Algorithm > Programmers' 카테고리의 다른 글
[Java] 완전탐색 - 모의고사(Lv1) (0) | 2022.08.04 |
---|---|
[Java] 완전탐색 - 피로도 (Lv2) (0) | 2022.08.04 |
[Java] 완전 탐색 - 소수 찾기 (Lv2) (0) | 2022.08.04 |
[Java] 연습문제 - 줄 서는 방법 (Lv2) (0) | 2022.08.03 |
[Java] 연습문제 - N개의 최소공배수 (Lv2) (0) | 2022.08.03 |