[LeetCode]Shortest path in binary matrix

Icarus<Wing>ยท2025๋…„ 5์›” 9์ผ
post-thumbnail

https://leetcode.com/problems/shortest-path-in-binary-matrix/description/

๐Ÿ“œ๋ฌธ์ œ ํ•ด์„

n x n ์ด์ง„ ํ–‰๋ ฌ grid๊ฐ€ ์ฃผ์–ด์กŒ์„ ๋•Œ, ํ–‰๋ ฌ์—์„œ ๊ฐ€์žฅ ์งง์€ clear path๋ฅผ ๋ฆฌํ„ดํ•˜๋ผ.(๋‹จ, clear path๊ฐ€ ์—†์œผ๋ฉด -1์„ ๋ฆฌํ„ดํ•˜๋ผ)

clear path: (0,0) -> (n-1, n-1)๋กœ ๊ฐ€๋Š” path๋ฅผ ๋งํ•จ:
1. path์˜ ๋ชจ๋“  ๋ฐฉ๋ฌธํ•œ ์…€๋“ค์€ 0์ด๋‹ค.
2. path์˜ ์ธ์ ‘ํ•œ ์…€๋“ค์€ 8-directionally๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค.(๊ทธ๊ฒƒ๋“ค์€ ๋ชจ๋‘ ๋‹ค๋ฅด๊ณ , ๊ทธ๊ฒƒ๋“ค์€ ๊ฐ„์„  ๋˜๋Š” ๊ตฌ์„์„ ๊ณต์œ ํ•œ๋‹ค.)
3. clear path์˜ ๊ธธ์ด๋Š” ๋ฐฉ๋ฌธํ•œ ์…€๋“ค์˜ ์ˆ˜์ด๋‹ค.

๐Ÿšง์ œ์•ฝ ์กฐ๊ฑด
1. m = row, n = col
2. 1 <= m, n <= 100
=> m*n = 10000 < 10^8 ์ด๋ฏ€๋กœ brute-force ๊ฐ€๋Šฅ
3. grid[i][j]๋Š” 0 ๋˜๋Š” 1์ด๋‹ค.

โš™๏ธ์ฝ”๋“œ ์„ค๊ณ„

  1. (0,0) ๋˜๋Š” (n-1, n-1)์ด 1์ด๋ฉด clear path๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ -1์„ ๋ฆฌํ„ด
  2. dfs๋กœ ํ•˜๋ฉด 0์ด ํ‘œ์‹œ๋œ ์…€๋“ค์€ ๋ฌด์กฐ๊ฑด ๋ฐฉ๋ฌธํ•˜๊ธฐ ๋•Œ๋ฌธ์— shorest path๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ x => bfs ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์„ ํƒ
  3. bfs ํ•จ์ˆ˜ ํ…œํ”Œ๋ฆฟ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, Tree์—์„œ ํ–ˆ๋˜ ์ปค์Šคํ…€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์…€๋งˆ๋‹ค ๋ฐฉ๋ฌธํ•œ ํšŸ์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

๐Ÿ’ป์ฝ”๋“œ ๊ตฌํ˜„

public class ShortestPathSolution {
    public int shortestPathBinaryMatrix(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        final int[] dr = {-1, 1, 0, 0, -1, 1, 1, -1};
        final int[] dc = {0, 0, -1, 1, -1, 1, -1, 1};
        boolean[][] visited = new boolean[m][n];
        int count = 0;

        // ์‹œ์  ๋˜๋Š” ์ข…์ ์ด 1์ด๋ฉด clear path๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ -1์„ ๋ฆฌํ„ด
        if (grid[0][0] == 1 || grid[m - 1][n - 1] == 1) {
            return -1;
        }

        // ์™„์ „ ํƒ์ƒ‰
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0 && !visited[i][j]) {
                    // bfs ํƒ์ƒ‰ ์‹œ์ž‘
                    visited[i][j] = true;
                    Queue<Point> q = new LinkedList<>();
                    q.offer(new Point(i, j, 1));

                    while (!q.isEmpty()) {
                        Point cur = q.poll();
                        int startR = cur.r;
                        int startC = cur.c;
                        int curCount = cur.count;

                        // ์—…๋ฐ์ดํŠธ
                        count = Math.max(count, curCount);

                        // ํ˜„์žฌ ์ขŒํ‘œ๊ฐ€ ์ข…์ ์ด๋ฉด count๋ฅผ ๋ฆฌํ„ด
                        if ((startR == m - 1) && (startC == n - 1)) {
                            return count;
                        }

                        for (int k = 0; k < 8; k++) {
                            int nextR = startR + dr[k];
                            int nextC = startC + dc[k];

                            if ((nextR >= 0 && nextR < m) && (nextC >= 0 && nextC < n) && grid[nextR][nextC] == 0 && !visited[nextR][nextC]) {
                                visited[nextR][nextC] = true;
                                q.offer(new Point(nextR, nextC, curCount + 1));
                            }
                        }
                    }
                    return -1;

                }
            }
        }
        return count;
    }

    private static class Point {
        int r;
        int c;
        int count;

        public Point(int r, int c, int count) {
            this.r = r;
            this.c = c;
            this.count = count;
        }
    }
}

๐Ÿ“–์Šคํ† ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:
1. ์‹œ์  ๋˜๋Š” ์ข…์ ์ด 1์ด๋ฉด clear path๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ -1์„ ๋ฆฌํ„ด
2. ์™„์ „ ํƒ์ƒ‰์„ ํ•˜๋Š”๋ฐ ํ˜„์žฌ ์ขŒํ‘œ๊ฐ€ (0,0)์ด๋ฉด bfs ํƒ์ƒ‰ ์‹œ์ž‘
2-1) ์…€์„ ๋ฐฉ๋ฌธํ•  ๋•Œ๋งˆ๋‹ค count 1์”ฉ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.
๐Ÿ“ข์ด๋•Œ ์ฃผ์˜ํ•  ์ ์ด 8-directionally๋กœ ํƒ์ƒ‰ํ•  ๋•Œ (nextR, nextC)์„ sibling Node์ฒ˜๋Ÿผ ์ทจ๊ธ‰์„ ํ•ด์„œ ๋ฐฉ๋ฌธํ•˜๋ ค๊ณ  ํ•˜๋Š” ์…€์— curCount + 1๋กœ ๋”ฐ๋กœ๋”ฐ๋กœ ์ฒ˜๋ฆฌํ•ด์ค˜์•ผ ํ•œ๋‹ค.
2-2) ํ˜„์žฌ ์ขŒํ‘œ๊ฐ€ ์ข…์ ์ด๋ฉด ์—…๋ฐ์ดํŠธ์‹œํ‚จ count๋ฅผ ๋ฆฌํ„ด


๐Ÿค–clear path์ฒ˜๋Ÿผ ๊ฒฝ๋กœ๊ฐ€ ์ •ํ•ด์ง„ grid๋Š” ์œ„์™€ ๊ฐ™์ด ์™„์ „ ํƒ์ƒ‰์„ ํ•  ํ•„์š”๊ฐ€ ์—†๊ณ  grid[0][0]์ผ ๋•Œ bfs ํƒ์ƒ‰์„ ๋ฐ”๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

  • ์ฆ‰, ์ด์ „์˜ num of islands ๋ฌธ์ œ๋Š” ๊ฒฝ๋กœ๊ฐ€ ์ •ํ•ด์ง€์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฌ๋“ค์„ ํƒ์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์™„์ „ ํƒ์ƒ‰์„ ํ•  ์ˆ˜ ๋ฐ–์— ์—†๋‹ค๋Š” ๊ฒƒ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.

๐Ÿ’ป์ˆ˜์ •๋œ ์ฝ”๋“œ ๊ตฌํ˜„

public class ShortestPathSolution {
    public int shortestPathBinaryMatrix(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        final int[] dr = {-1, 1, 0, 0, -1, 1, 1, -1};
        final int[] dc = {0, 0, -1, 1, -1, 1, -1, 1};
        boolean[][] visited = new boolean[m][n];

        // ์‹œ์  ๋˜๋Š” ์ข…์ ์ด 1์ด๋ฉด clear path๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ -1์„ ๋ฆฌํ„ด
        if (grid[0][0] == 1 || grid[m - 1][n - 1] == 1) {
            return -1;
        }

        // (0,0)์ด 0์ด๋ฉด bfs ํƒ์ƒ‰ ์‹œ์ž‘
        if (grid[0][0] == 0) {
            // bfs ํƒ์ƒ‰ ์‹œ์ž‘
            visited[0][0] = true;
            Queue<Point> q = new LinkedList<>();
            q.offer(new Point(0, 0, 1));

            while (!q.isEmpty()) {
                Point cur = q.poll();
                int startR = cur.r;
                int startC = cur.c;
                int curCount = cur.count;

                // ํ˜„์žฌ ์ขŒํ‘œ๊ฐ€ ์ข…์ ์ด๋ฉด count๋ฅผ ๋ฆฌํ„ด
                if ((startR == m - 1) && (startC == n - 1)) {
                    return curCount;
                }

                for (int k = 0; k < 8; k++) {
                    int nextR = startR + dr[k];
                    int nextC = startC + dc[k];

                    if ((nextR >= 0 && nextR < m) && (nextC >= 0 && nextC < n) && grid[nextR][nextC] == 0 && !visited[nextR][nextC]) {
                        visited[nextR][nextC] = true;
                        q.offer(new Point(nextR, nextC, curCount + 1));
                    }
                }
            }

        }
        return -1;
    }

    private static class Point {
        int r;
        int c;
        int count;

        public Point(int r, int c, int count) {
            this.r = r;
            this.c = c;
            this.count = count;
        }
    }
}
  • ๐Ÿ’กmax depth in a binary tree๋ฌธ์ œ๋Š” "๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธ"ํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ฐ€์žฅ ๊นŠ์€ ๋ ˆ๋ฒจ์„ ์ถ”์ ํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ์ „์—ญ ๋ณ€์ˆ˜(ํ˜น์€ ๋ฉ”์„œ๋“œ ์Šค์ฝ”ํ”„ ๋ณ€์ˆ˜)๋กœ ์ตœ๋Œ€๊ฐ’์„ ๊ณ„์† ์—…๋ฐ์ดํŠธํ•ด์ค˜์•ผ ํ•œ๋‹ค.
    • ๋ฐ˜๋ฉด์— ์ด๋ฒˆ ๋ฌธ์ œ๋Š” ๋ชฉ์ ์ง€์—๋งŒ ๋„๋‹ฌํ•˜๋ฉด ์ฆ๊ฐ€์‹œํ‚จ count๋งŒ ๋ฆฌํ„ดํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ตณ์ด ๋ฉ”์„œ๋“œ ๋ ˆ๋ฒจ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์„œ Math.max(count, curCount)๋กœ ์—…๋ฐ์ดํŠธ์‹œํ‚ฌ ํ•„์š”๊ฐ€ ์—†๋‹ค.
profile
๋ชจ๋“  ์ฝ”๋“œ์—๋Š” ์ด์œ ๊ฐ€ ์žˆ๊ธฐ์— ์›์ธ์„ ํŒŒ์•…ํ•  ๋•Œ๊นŒ์ง€ ์ง‘์š”ํ•˜๊ฒŒ ํƒ๊ตฌํ•˜๋Š” ๊ฒƒ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€