From 01628146fa2a67fa9739b3e8ac72da6ad9066734 Mon Sep 17 00:00:00 2001 From: ICE0208 Date: Thu, 6 Aug 2026 16:39:23 +0900 Subject: [PATCH 1/6] number of islands --- number-of-islands/ICE0208.java | 89 ++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 number-of-islands/ICE0208.java diff --git a/number-of-islands/ICE0208.java b/number-of-islands/ICE0208.java new file mode 100644 index 0000000000..b383e82992 --- /dev/null +++ b/number-of-islands/ICE0208.java @@ -0,0 +1,89 @@ +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 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; + } +} From 68d9ad4dc87b081a372a9a0705114b64f2fd510c Mon Sep 17 00:00:00 2001 From: ICE0208 Date: Fri, 7 Aug 2026 19:40:13 +0900 Subject: [PATCH 2/6] unique paths --- unique-paths/ICE0208.java | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 unique-paths/ICE0208.java diff --git a/unique-paths/ICE0208.java b/unique-paths/ICE0208.java new file mode 100644 index 0000000000..5d94bb330d --- /dev/null +++ b/unique-paths/ICE0208.java @@ -0,0 +1,48 @@ +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]; + } +} \ No newline at end of file From c560dd42cc51dd2fcff536f1fea044ecc7c5db2c Mon Sep 17 00:00:00 2001 From: ICE0208 Date: Fri, 7 Aug 2026 19:41:43 +0900 Subject: [PATCH 3/6] =?UTF-8?q?line=20lint=20=F0=9F=98=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- unique-paths/ICE0208.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unique-paths/ICE0208.java b/unique-paths/ICE0208.java index 5d94bb330d..5bc6369d13 100644 --- a/unique-paths/ICE0208.java +++ b/unique-paths/ICE0208.java @@ -45,4 +45,4 @@ public int uniquePaths(int m, int n) { return dp[n - 1]; } -} \ No newline at end of file +} From 269f59e14481e6426ad0a0389ed10f9af5b71e61 Mon Sep 17 00:00:00 2001 From: ICE0208 Date: Fri, 7 Aug 2026 20:14:41 +0900 Subject: [PATCH 4/6] set matrix zeros --- set-matrix-zeroes/ICE0208.java | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 set-matrix-zeroes/ICE0208.java diff --git a/set-matrix-zeroes/ICE0208.java b/set-matrix-zeroes/ICE0208.java new file mode 100644 index 0000000000..92aa9d1951 --- /dev/null +++ b/set-matrix-zeroes/ICE0208.java @@ -0,0 +1,54 @@ +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; + } + } + } +} From 8b9d76b0634517e61bcc9486acd50dfec7f94f5d Mon Sep 17 00:00:00 2001 From: ICE0208 Date: Sat, 8 Aug 2026 10:13:08 +0900 Subject: [PATCH 5/6] reverse linked list --- reverse-linked-list/ICE0208.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 reverse-linked-list/ICE0208.java diff --git a/reverse-linked-list/ICE0208.java b/reverse-linked-list/ICE0208.java new file mode 100644 index 0000000000..d2f634db7b --- /dev/null +++ b/reverse-linked-list/ICE0208.java @@ -0,0 +1,17 @@ +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; + } +} From eb42775e43395e2c5c88c2ff7475445ebb13bc63 Mon Sep 17 00:00:00 2001 From: ICE0208 Date: Sat, 8 Aug 2026 10:15:16 +0900 Subject: [PATCH 6/6] longest substring without repeating character --- .../ICE0208.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 longest-substring-without-repeating-characters/ICE0208.java diff --git a/longest-substring-without-repeating-characters/ICE0208.java b/longest-substring-without-repeating-characters/ICE0208.java new file mode 100644 index 0000000000..587b243b21 --- /dev/null +++ b/longest-substring-without-repeating-characters/ICE0208.java @@ -0,0 +1,25 @@ +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; + } +}