'X'는 바다, 숫자는 섬으로 이뤄진 문자열 배열이 주어진다. 숫자는 1~9까지로 이뤄지며, 식량을 의미한다. 숫자가 상,하,좌,우로 연결된 섬은 하나의 섬이며, 이 때 각 섬마다 최대 며칠씩 머물 수 있는지 배열에 오름차순으로 담아 반환하라
maps | result |
---|---|
["X591X","X1X5X","X231X", "1XXX1" | [1, 1, 27] |
["XXX","XXX","XXX"] | [-1] |
maps[i]
의 길이≤100maps[i]
의 요소≤9BFS(Brute Force)
사용ArrayList
에 결과값 저장(1) 주어진 maps
를 편리하게 이용하기 위해 이중 배열로 초기화
'X'
는 -1
로 초기화한다.(2) 이중 for문을 통해 칸 전체를 탐색한다.
-1
이 아님으로 BFS
함수로 해당 x
, y
값을 보낸다.(3) Queue
를 선언하여, 다음으로 이동할 칸의 x
, y
값을 넣는다.
(4) 섬의 전체 식량을 계산하기 위해 sum
을 선언하고, 연결된 다른 칸에 방문할 때마다 해당 칸의 숫자를 sum
에 누적합한다.
(5) 이미 방문한 섬은 -1
로 설정하여, 다시 방문하지 않도록 설정한다.
(6) 하나의 섬에 연결된 모든 칸의 식량이 최종 sum에 저장되며, 해당 값을 반환한다.
(7) 반환 받은 sum
을 ArrayList
에 넣고, 만일 ArrayList
의 길이가 0이라면 방문 가능한 섬이 없음을 의미하기에 -1
을 넣는다.
import java.util.*;
class Solution {
static int N, M;
static int[][] board;
public ArrayList<Integer> solution(String[] maps) {
int[] answer = {};
N = maps.length;
M = maps[0].length();
board = new int[N][M];
ArrayList<Integer> list = new ArrayList<>();
for(int i=0;i<N;i++) {
for(int j=0;j<M;j++) {
char c = maps[i].charAt(j);
if (c == 'X') board[i][j] = -1;
else board[i][j] = c -'0';
}
}
for(int i=0;i<N;i++) {
for(int j=0;j<M;j++) {
if (board[i][j] != -1)
list.add(bfs(i,j));
}
}
Collections.sort(list);
if (list.size() == 0)
list.add(-1);
return list;
}
private static int bfs(int x, int y) {
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{x,y});
int sum = board[x][y];
board[x][y]=-1;
int[] mx = {0,0,1,-1};
int[] my = {1,-1,0,0};
while (!queue.isEmpty()) {
int[] cur = queue.poll();
for(int i=0;i<4;i++) {
int nx = cur[0] + mx[i];
int ny = cur[1] + my[i];
if (nx < 0 || ny < 0 || nx >= N || ny >= M)
continue;
if (board[nx][ny] == -1)
continue;
queue.add(new int[]{nx,ny});
sum += board[nx][ny];
board[nx][ny] = -1;
}
}
return sum;
}
}
DFS를 이용하여 board
의 각 구간에 누적합을 하는 방식을 시도했지만, 뭔가 답은 나오는데 구체적으로 잡히진 않았다. 최종 결과값만 ArrayList에 넣을지 같은 그런 감들. 아직 익숙하지 않는 듯 하여 BFS로 방식을 변경하였다.
※ 풀었다!
import java.util.*;
class Solution {
static boolean[][] visited;
static int[][] board;
static int N,M;
static int[] mx = {0,0,1,-1};
static int[] my = {1,-1,0,0};
static ArrayList<Integer> list;
public ArrayList<Integer> solution(String[] maps) {
int[] answer = {};
N = maps.length;
M = maps[0].length();
board = new int[N][M];
list = new ArrayList<>();
for(int i=0;i<N;i++) {
for(int j=0;j<M;j++) {
char c = maps[i].charAt(j);
if (c == 'X') board[i][j] = -1;
else board[i][j] = c -'0';
}
}
int result = 0;
for(int i=0;i<N;i++) {
for (int j=0;j<M;j++) {
if (board[i][j] != -1) {
result = dfs(i,j, result);
list.add(result);
result = 0;
}
}
}
if (list.size() == 0)
list.add(-1);
Collections.sort(list);
return list;
}
private static int dfs(int x, int y, int result) {
result += board[x][y];
board[x][y] = -1;
for(int i=0;i<4;i++) {
int nx = x + mx[i];
int ny = y + my[i];
if (nx < 0 || ny < 0 || nx >= N || ny >= M)
continue;
if (board[nx][ny]==-1)
continue;
result = dfs(nx,ny,result);
}
return result;
}
}
DFS보다는 BFS가 재귀 호출을 안 해서 머리 속으로 쉽게 시뮬레이션되었다. 암튼 잘 돌아간다. :>
이번 문제로 내가 BFS보다는 DFS 풀이에 취약함을 알았다. 해결 방안은 많이 풀어 보는 것 외는 없다. 킵고잉~