Skip to content

[ICE0208] WEEK 07 Solutions - #2798

Merged
ICE0208 merged 6 commits into
DaleStudy:mainfrom
ICE0208:week07
Aug 8, 2026
Merged

[ICE0208] WEEK 07 Solutions#2798
ICE0208 merged 6 commits into
DaleStudy:mainfrom
ICE0208:week07

Conversation

@ICE0208

@ICE0208 ICE0208 commented Aug 6, 2026

Copy link
Copy Markdown
Member

답안 제출 문제

작성자 체크 리스트

  • Projects의 오른쪽 버튼(▼)을 눌러 확장한 뒤, Week를 현재 주차로 설정해주세요.
  • 문제를 모두 푸시면 프로젝트에서 StatusIn Review로 설정해주세요.
  • 코드 검토자 1분 이상으로부터 승인을 받으셨다면 PR을 병합해주세요.

검토자 체크 리스트

Important

본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!

  • 바로 이전에 올라온 PR에 본인을 코드 리뷰어로 추가해주세요.
  • 본인이 검토해야하는 PR의 답안 코드에 피드백을 주세요.
  • 토요일 전까지 PR을 병합할 수 있도록 승인해주세요.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

number-of-islands/ICE0208.java
import java.util.ArrayDeque;
import java.util.Deque;

class Solution {
    private static final int[][] DIRECTIONS = {
            {0, 1},
            {0, -1},
            {1, 0},
            {-1, 0}
    };

    private static final char WATER = '0';
    private static final char LAND = '1';

    private record Position(int row, int column) {
    }

    /**
     * 격자를 순회하며 아직 방문하지 않은 육지를 발견할 때마다
     * 연결된 하나의 섬을 반복형 DFS로 모두 방문 처리한다.
     *
     * 시간 복잡도: O(m * n)
     * 공간 복잡도: O(m * n)
     */
    public int numIslands(char[][] grid) {
        int islandCount = 0;

        for (int row = 0; row < grid.length; row++) {
            for (int column = 0; column < grid[row].length; column++) {
                if (grid[row][column] != LAND) {
                    continue;
                }

                // 아직 방문하지 않은 육지는 새로운 섬의 시작점이다.
                islandCount++;
                markIslandAsVisited(grid, row, column);
            }
        }

        return islandCount;
    }

    /**
     * 시작 위치와 상하좌우로 연결된 모든 육지를 방문 처리한다.
     * 재귀 호출로 인한 스택 오버플로를 피하기 위해 별도의 스택을 사용한다.
     */
    private static void markIslandAsVisited(
            char[][] grid,
            int startRow,
            int startColumn
    ) {
        Deque<Position> stack = new ArrayDeque<>();
        stack.push(new Position(startRow, startColumn));

        // 스택에 넣는 시점에 방문 처리하여 같은 위치가 중복으로 들어가는 것을 방지한다.
        grid[startRow][startColumn] = WATER;

        while (!stack.isEmpty()) {
            Position current = stack.pop();

            for (int[] direction : DIRECTIONS) {
                int nextRow = current.row() + direction[0];
                int nextColumn = current.column() + direction[1];

                if (!isInBounds(grid, nextRow, nextColumn)) {
                    continue;
                }

                if (grid[nextRow][nextColumn] != LAND) {
                    continue;
                }

                grid[nextRow][nextColumn] = WATER;
                stack.push(new Position(nextRow, nextColumn));
            }
        }
    }

    private static boolean isInBounds(
            char[][] grid,
            int row,
            int column
    ) {
        return row >= 0
                && row < grid.length
                && column >= 0
                && column < grid[0].length;
    }
}
  • 패턴: Depth-First Search, Stack/Explicit Stack (as part of DFS)
  • 설명: 그리드를 순회하며 섬(연결된 육지)을 DFS로 방문 처리한다. 재귀 대신 스택을 사용해 DFS를 구현하고, 인접한 육지를 탐색하며 방문 표식을 남긴다.

📊 시간/공간 복잡도 분석

유저 분석 실제 분석 결과
Time O(m * n) O(n * m)
Space O(m * n) O(n * m)

피드백: 두 방향으로의 인접만 확장하는 DFS로 전체 격자를 한 번씩 방문하고, 방문 시 육지를 WATER로 표시해 중복 방문을 막는다.

개선 제안: 현재 구현이 적절해 보입니다.

@dalestudy

dalestudy Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📊 ICE0208 님의 학습 현황

이번 주 제출 문제

문제 난이도 유형 분석
longest-substring-without-repeating-characters Medium ✅ 의도한 유형
number-of-islands Medium ✅ 의도한 유형
reverse-linked-list Easy ✅ 의도한 유형
set-matrix-zeroes Medium ✅ 의도한 유형
unique-paths Medium ✅ 의도한 유형

누적 학습 요약

  • 풀이한 문제: 30 / 75개
  • 이번 주 유형 일치율: 100% (5문제 중 5문제 일치)

문제 풀이 현황

카테고리 진행도 완료
Array ■■■■■■□ 8 / 10 (Medium 5, Easy 3)
Dynamic Programming ■■■■□□□ 7 / 11 (Easy 1, Medium 6)
Matrix ■■■■□□□ 2 / 4 (Medium 2)
String ■■■■□□□ 5 / 10 (Medium 2, Easy 3)
Heap ■■□□□□□ 1 / 3 (Medium 1)
Tree ■■□□□□□ 4 / 14 (Medium 3, Easy 1)
Binary ■□□□□□□ 1 / 5 (Easy 1)
Linked List ■□□□□□□ 1 / 6 (Easy 1)
Graph ■□□□□□□ 1 / 8 (Medium 1)
Interval □□□□□□□ 0 / 5 ← 아직 시작 안 함

🤖 이 댓글은 GitHub App을 통해 자동으로 작성되었습니다.

🔢 API 사용량 (gpt-5-nano)
요청 입력 토큰 출력 토큰 합계 비용
1 802 37 839 $0.000055
2 1,394 126 1,520 $0.000120
3 1,394 116 1,510 $0.000116
4 2,020 149 2,169 $0.000161
5 2,686 208 2,894 $0.000218
합계 8,296 636 8,932 $0.000669

@dolphinflow86
dolphinflow86 self-requested a review August 6, 2026 11:42
Comment thread unique-paths/ICE0208.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

unique-paths/ICE0208.java
import java.util.Arrays;

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        // 첫 번째 행과 열은 한 방향으로만 이동해 도달할 수 있으므로 1로 초기화합니다.
        initializeBaseCases(dp);

        for (int row = 1; row < m; ++row) {
            for (int col = 1; col < n; ++col) {
                dp[row][col] = dp[row - 1][col] + dp[row][col - 1];
            }
        }

        return dp[m - 1][n - 1];
    }

    /**
        * DP 배열의 첫 번째 행과 첫 번째 열을 1로 초기화합니다.
        * @param dp 초기화할 DP 배열
        */
    private static void initializeBaseCases(int[][] dp) {
        int rows = dp.length;
        int cols = dp[0].length;

        for (int row = 0; row < rows; row++) {
            dp[row][0] = 1;
        }
        for (int col = 0; col < cols; col++) {
            dp[0][col] = 1;
        }
    }
}

class Solution2 {
    public int uniquePaths(int m, int n) {
        int[] dp = new int[n];
        Arrays.fill(dp, 1);

        for (int row = 1; row < m; ++row) {
            for (int col = 1; col < n; ++col) {
                dp[col] += dp[col - 1];
            }
        }

        return dp[n - 1];
    }
}
  • 패턴: Dynamic Programming, Greedy
  • 설명: 코드는 두 가지 방식으로 경로의 수를 DP로 계산합니다. 2D 배열과 1D 배열 모두에서 현재 위치의 경로 수를 위/좌의 합으로 갱신하므로 DP 패턴에 속합니다. 주어진 문제의 해를 작은 부분 문제로 나누어 해결하는 특징이 명확합니다.

📊 시간/공간 복잡도 분석

ℹ️ 이 파일에는 2가지 풀이가 포함되어 있어 각각 분석합니다.

풀이 1: Solution.uniquePaths — Time: O(m*n) / Space: O(m*n)
복잡도
Time O(m*n)
Space O(m*n)

피드백: 2차원 DP 배열을 사용해 이웃 셀의 합으로 현재 셀의 경로 수를 계산합니다.

개선 제안: 현재 구현은 명확하지만 메모리 사용을 줄이려면 공간 최적화 버전(1차원 DP)을 사용할 수 있습니다.

풀이 2: Solution2.uniquePaths — Time: O(m*n) / Space: O(n)
복잡도
Time O(m*n)
Space O(n)

피드백: 1차원 배열 dp를 통해 메모리 사용량을 줄였고, 각 행마다 이전 열의 값을 이용해 현재 값을 업데이트한다.

개선 제안: 추가적으로 커스텀 최적화나 초기화 로직을 간소화해도 좋다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Comment thread unique-paths/ICE0208.java

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

unique-paths/ICE0208.java
import java.util.Arrays;

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        // 첫 번째 행과 열은 한 방향으로만 이동해 도달할 수 있으므로 1로 초기화합니다.
        initializeBaseCases(dp);

        for (int row = 1; row < m; ++row) {
            for (int col = 1; col < n; ++col) {
                dp[row][col] = dp[row - 1][col] + dp[row][col - 1];
            }
        }

        return dp[m - 1][n - 1];
    }

    /**
        * DP 배열의 첫 번째 행과 첫 번째 열을 1로 초기화합니다.
        * @param dp 초기화할 DP 배열
        */
    private static void initializeBaseCases(int[][] dp) {
        int rows = dp.length;
        int cols = dp[0].length;

        for (int row = 0; row < rows; row++) {
            dp[row][0] = 1;
        }
        for (int col = 0; col < cols; col++) {
            dp[0][col] = 1;
        }
    }
}

class Solution2 {
    public int uniquePaths(int m, int n) {
        int[] dp = new int[n];
        Arrays.fill(dp, 1);

        for (int row = 1; row < m; ++row) {
            for (int col = 1; col < n; ++col) {
                dp[col] += dp[col - 1];
            }
        }

        return dp[n - 1];
    }
}
  • 패턴: Dynamic Programming, Monotonic Stack
  • 설명: 두 가지 풀이 모두 DP를 이용한 경로 수 계산 패턴으로 각 셀의 경로 수를 합산합니다. 또한 두 번째 풀이에서 1차원 DP 배열로 공간 최적화하는 일반적 DP 패턴이 보입니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(m*n)
Space O(m*n)

피드백: 2D 배열 버전은 직관적이고 이해하기 쉽고, 1D 배열 버전은 공간을 절약합니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

set-matrix-zeroes/ICE0208.java
import java.util.Arrays;

class Solution {
    public void setZeroes(int[][] matrix) {
        int rows = matrix.length;
        int cols = matrix[0].length;

        // 첫 번째 행과 열은 marker로 사용하므로, 원래 0이 있었는지 별도로 저장한다.
        boolean firstRowHasZero = false;
        for (int col = 0; col < cols; ++col) {
            if (matrix[0][col] == 0) {
                firstRowHasZero = true;
                break;
            }
        }

        boolean firstColumnHasZero = false;
        for (int row = 0; row < rows; ++row) {
            if (matrix[row][0] == 0) {
                firstColumnHasZero = true;
                break;
            }
        }

        // 첫 번째 행과 열을 각 행과 열의 zero marker로 사용한다.
        for (int row = 1; row < rows; ++row) {
            for (int col = 1; col < cols; ++col) {
                if (matrix[row][col] == 0) {
                    matrix[row][0] = 0;
                    matrix[0][col] = 0;
                }
            }
        }

        // marker를 기준으로 내부 원소를 0으로 변경한다.
        for (int row = 1; row < rows; ++row) {
            for (int col = 1; col < cols; ++col) {
                if (matrix[row][0] == 0 || matrix[0][col] == 0) {
                    matrix[row][col] = 0;
                }
            }
        }

        if (firstRowHasZero) {
            Arrays.fill(matrix[0], 0);
        }

        if (firstColumnHasZero) {
            for (int row = 0; row < rows; ++row) {
                matrix[row][0] = 0;
            }
        }
    }
}
  • 패턴: Greedy, Dynamic Programming, Divide and Conquer, Two Pointers, Hash Map / Hash Set, Binary Search, Monotonic Stack, Heap / Priority Queue, DFS, BFS, Backtracking, Union Find, Trie, Bit Manipulation, Sliding Window
  • 설명: 이 코드는 2D 매트릭스에서 특정 행/열을 마커로 이용해 제로를 확산시키는 문제로, 공간을 추가로 사용하지 않고 기존 행/열을 마커로 재활용하는 방식이 핵심이다. 제한된 공간에서 상태를 저장하고 조건에 따라 원소를 업데이트하는 아이디어는 다수의 공간 최적화 패턴과 연관된다.

📊 시간/공간 복잡도 분석

복잡도
Time O(m * n)
Space O(1)

피드백: 입력 행렬에 추가적인 공간을 사용하지 않고, 첫 행/열을 마커로 활용하여 전체 원소를 한 번씩 스캔한다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

longest-substring-without-repeating-characters/ICE0208.java
import java.util.Arrays;

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int [] lastSeen = new int[128];
        Arrays.fill(lastSeen, -1);

        int left = 0;
        int maxLength = 0;

        for (int right = 0; right < s.length(); right++) {
            char current = s.charAt(right);

            // 현재 문자가 이미 등장했다면
            // 이전 등장 위치 다음으로 left를 이동한다.
            // left는 right 보다 작거나 같다는 것이 보장.
            left = Math.max(left, lastSeen[current] + 1);

            lastSeen[current] = right;
            maxLength = Math.max(maxLength, right - left + 1);
        }

        return maxLength;
    }
}
  • 패턴: Two Pointers, Hash Map / Hash Set, Sliding Window
  • 설명: 문자열에서 서로 다른 부분문자열의 길이를 왼쪽과 오른쪽 포인터로 탐색하며, 각 문자의 마지막 등장 위치를 저장해 중복을 제거하는 슬라이딩 윈도우 패턴의 구현이다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(1)

피드백: 고정 크기 배열과 원소 위치 추적으로 각 문자의 마지막 위치를 기록하고 윈도우를 좌측으로 이동시킨다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

reverse-linked-list/ICE0208.java
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode current = head;
        
        while (current != null) {
            ListNode next = current.next;
            
            current.next = prev;
            
            prev = current;
            current = next;
        }
        
        return prev;
    }
}
  • 패턴: Two Pointers, Linked List
  • 설명: 두 포인터(prev, current)로 단일 연결 리스트를 뒤집는 전형적인 패턴으로 두 포인터를 이용해 노드 연결 방향을 역전시킨다. 반복문으로 노드를 순회하며 인접한 관계를 재설정한다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(1)

피드백: 커서 변수들(prev, current, next)를 사용해 포인터를 역전시킨다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

@ICE0208 ICE0208 moved this from Solving to In Review in 리트코드 스터디 8기 Aug 8, 2026

@dolphinflow86 dolphinflow86 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!


class Solution {
public int lengthOfLongestSubstring(String s) {
int [] lastSeen = new int[128];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문제에서 주어지는 입력값인 아스키 코드 값 범위로 제한두신것이 인상적이네요!
저는 set을 사용했는데 spacial locality, 캐시 히트율 등에서도 배열로 구현한게 더 좋아보입니다.

Comment thread unique-paths/ICE0208.java
Comment on lines +3 to +16
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
// 첫 번째 행과 열은 한 방향으로만 이동해 도달할 수 있으므로 1로 초기화합니다.
initializeBaseCases(dp);

for (int row = 1; row < m; ++row) {
for (int col = 1; col < n; ++col) {
dp[row][col] = dp[row - 1][col] + dp[row][col - 1];
}
}

return dp[m - 1][n - 1];
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깔끔하게 잘 풀여주셨네요. 다만 시간, 공간복잡도 분석을 주석에 같이 써주시면 좋을 것 같습니다!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰 감사합니다!  🙌
다음주 문제풀이부터는 주석에 복잡도도 분석해서 남겨놓아야겠네요 🫡

@ICE0208
ICE0208 merged commit 7f50376 into DaleStudy:main Aug 8, 2026
1 check passed
@github-project-automation github-project-automation Bot moved this from In Review to Completed in 리트코드 스터디 8기 Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Completed

Development

Successfully merging this pull request may close these issues.

2 participants