ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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)에 수행할 수 있기 때문에 더 효율적입니다.

     

    총평

    자바 코테 연습을 꾸준히 하자.

     

Designed by Tistory.