-
99클럽 코테 스터디 10일차 TIL - 익숙한 문제는 빠르게 풀기Coding Test 2024. 4. 3. 19:11
문제 - 무인도 여행 문제링크
문제 설명
2차원 격자 maps가 주어지고, 격자는 바다를 의미하는 'X'와 1~9 사이의 숫자로 이루어져 있습니다.
해당 칸이 숫자라면 땅을 의미하고, 상하좌우로 서로 연결된 땅은 하나의 섬입니다.
maps 내의 모든 섬에 방문할 때, 각 섬에 적혀있는 모든 숫자를 다 더한 값을 담아 반환하면 됩니다.
풀이 과정
일반적인 BFS 섬 찾기 문제입니다. maps를 2중 for 문 순회하며 섬을 찾아 마킹하며 숫자를 더한 후 BFS가 끝나면 더한 값을 저장해 놓다가 모든 순회가 끝나면 반환하면 됩니다.
from collections import deque def solution(maps): answer = [] n = len(maps) m = len(maps[0]) dx = [1, 0, -1, 0] dy = [0, 1, 0, -1] vis = [[False for _ in range(m)] for _ in range(n)] dq = deque() for i in range(n): for j in range(m): if maps[i][j] == 'X' or vis[i][j]: continue vis[i][j] = True dq.append((i, j)) cnts = int(maps[i][j]) while dq: x, y = dq.popleft() for k in range(4): nx = x + dx[k] ny = y + dy[k] if nx < 0 or nx >= n or ny < 0 or ny >= m: continue if maps[nx][ny] == 'X' or vis[nx][ny: continue vis[nx][ny] = True cnts += int(maps[nx][ny]) dq.append((nx, ny)) answer.append(cnts) if answer: answer.sort() return answer return [-1]
Java 코테 연습을 할겸 Java로도 풀어보았습니다.
import java.util.*; class Solution { public int[] solution(String[] maps) { List<Integer> lst = new ArrayList<>(); int n = maps.length; int m = maps[0].length(); boolean[][] vis = new boolean[n][m]; int[] dx = {1, 0, -1, 0}; int[] dy = {0, 1, 0, -1}; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (maps[i].charAt(j) == 'X' || vis[i][j]) { continue; } lst.add(bfs(maps, vis, i, j, dx, dy)); } } Collections.sort(lst); if (lst.isEmpty()) { return new int[] {-1}; } return lst.stream().mapToInt(Integer::intValue).toArray(); } private int bfs(String[] maps, boolean[][] vis, int x, int y, int[] dx, int[] dy) { int n = maps.length; int m = maps[0].length(); ArrayDeque<int[]> q = new ArrayDeque<>(); q.offer(new int[] {x, y}); vis[x][y] = true; int sum = maps[x].charAt(y) - '0'; while (!q.isEmpty()) { int[] cur = q.poll(); int cx = cur[0], cy = cur[1]; for (int i = 0; i < 4; i++) { int nx = cx + dx[i]; int ny = cy + dy[i]; if (nx < 0 || nx >= n || ny < 0 || ny >= m || maps[nx].charAt(ny) == 'X' || vis[nx][ny]) { continue; } vis[nx][ny] = true; q.offer(new int[] {nx, ny}); sum += maps[nx].charAt(ny) - '0'; } } return sum; } }
역시 파이썬보다 자바가 코드량이 훨씬 깁니다.
maps를 인덱스 접근할 때도 maps[i][j] 이렇게 하니 에러가 발생했습니다. maps는 String으로 이루어진 array이기 때문에 첫항은 []로 접근이 가능하지만, String은 charAt()으로 접근할 수 있기 때문입니다.
그리고 char타입을 int로 타입캐스팅하면 아스키코드 값이 반환되기 때문에, '6'과 같은 문자에서 6을 추출하기 위해서는 '6' - '0'같이 아스키코드 차이를 얻는 방법이 있습니다.
자바는 타입도 신경을 써줘야 해서 List로 받고 다시 반환타입인 int[]로 바꿔주는 작업이 필요했습니다.
lst.stream(lst).mapToInt(Integer::intValue).toArray();
위 코드로 바꿔줄 수 있는데 너무 깁니다..
파이썬 코드에서 사용하는 deque를 자바에서 대체할 자료구조는 LinkedList, ArrayDeque가 있습니다.
ArrayDeque이 양끝단 삽입삭제를 O(1)에 수행할 수 있기 때문에 더 효율적입니다.
총평
자바 코테 연습을 꾸준히 하자.
'Coding Test' 카테고리의 다른 글
99클럽 코테 스터디 12일차 TIL - 한계가 있는 풀이는 과감히 버리기 (0) 2024.04.05 99클럽 코테 스터디 11일차 TIL - 알고리즘의 원리를 정확히 알고있기 (2) 2024.04.04 99클럽 코테 스터디 9일차 TIL - 획기적인 풀이는 이해하고 넘어가자 (0) 2024.04.02 99클럽 코테 스터디 8일차 TIL - 좀 더 구조화된 답을 내보자 (0) 2024.04.01 99클럽 코테 스터디 7일차 TIL - 풀 수 있는 방법으로 바로 풀자 (0) 2024.03.31