diff --git a/number-of-islands/Geegong.java b/number-of-islands/Geegong.java new file mode 100644 index 000000000..bf8910431 --- /dev/null +++ b/number-of-islands/Geegong.java @@ -0,0 +1,56 @@ +public class Geegong { + + /** + * 1. 하나씩 훑어가면서 1이 되는 시점을 찾아 그 시점부터 dfs 로 방향값을 주어 + * 방문한 곳은 0으로 바꿔버려 다시는 탐색하지 못하도록 막아버림 + * 모든 방향값을 주면서 0으로 메꾼 후 1을 리턴하고 리턴된 값들을 누적하면 만들어낼 수 있는 섬의 총 갯수가 된다 + * time complexity : O (m*n*4) => O(m*n) + * space complexity : O(m*n) // 따로 memoization 을 위한 변수는 없으나 재귀로 인해 콜스택 발생 + */ + public static int[][] vectors = {{0,1}, {1,0}, {0,-1}, {-1,0}}; + public int numIslands(char[][] grid) { + + int totalNumberOfIslands = 0; + + for (int rowIdx=0; rowIdx < grid.length; rowIdx++) { + for (int colIdx=0; colIdx < grid[0].length; colIdx++) { + // 1이 되는 시점부터 섬이 되는지 체크한다. + if (grid[rowIdx][colIdx] == '1') { + totalNumberOfIslands += dfs(grid, rowIdx, colIdx); + } + } + } + return totalNumberOfIslands; + } + + public int dfs(char[][] origin, int rowIdx, int colIdx) { + if (rowIdx < 0 || colIdx < 0) { + // 의미 없는 리턴. 단순히 콜스택 이전으로 돌아가기 위해 임의값 리턴 + return 1; + } + + if (rowIdx >= origin.length || colIdx >= origin[0].length) { + // 의미 없는 리턴. 단순히 콜스택 이전으로 돌아가기 위해 임의값 리턴 + return 1; + } + + if (origin[rowIdx][colIdx] == '0') { + // 의미 없는 리턴. 단순히 콜스택 이전으로 돌아가기 위해 임의값 리턴 + return 1; + } + + origin[rowIdx][colIdx] = '0'; // 0 으로 셋팅해서 다음 섬을 찾을때 방문하지 못하도록 방어한다. + + for (int[] vector : vectors) { + int moveRow = vector[0]; + int moveCol = vector[1]; + + dfs(origin, rowIdx + moveRow, colIdx + moveCol); + } + + // 섬이 되는 구역을 다 돌았다면 하나의 섬이 하나 된다고 판단이 되므로 1 리턴 + return 1; + } + +} + diff --git a/set-matrix-zeroes/Geegong.java b/set-matrix-zeroes/Geegong.java new file mode 100644 index 000000000..9d6f0202a --- /dev/null +++ b/set-matrix-zeroes/Geegong.java @@ -0,0 +1,65 @@ +import java.util.Arrays; + +public class Geegong { + + + /** + * in-place 풀이여서 matrix 안에 0 으로 첫번째 row, column 에 0으로 채워야 하는 부분을 마킹해두는 식으로 풀이 + * time complexity : O(2MN) -> O(MN) + * space complexity : O(1) + * @param matrix + */ + public void setZeroes(int[][] matrix) { + + // 가장 자리 top, left 에 1이 있는 지 체크 + // in-place 라고 풀었는데 가장 자리에 1이 있는지 체크는 변수 한두개 정도는 써도 되는듯..? + boolean zeroExistsInTop = false; + boolean zeroExistsInLeft = false; + for (int colIndex=0; colIndex< matrix[0].length; colIndex++) { + if (matrix[0][colIndex] == 0) { + zeroExistsInTop = true; + break; + } + } + + for (int rowIndex = 0; rowIndex < matrix.length; rowIndex++) { + if (matrix[rowIndex][0] == 0) { + zeroExistsInLeft = true; + break; + } + } + + // 가장자리를 제외하고 안쪽에만 먼저 0으로 채워야되는 케이스들을 골라냄 + for (int rowIndex = 1; rowIndex < matrix.length; rowIndex++) { + for (int colIndex=1; colIndex < matrix[0].length; colIndex++) { + + if (matrix[rowIndex][colIndex] == 0) { + matrix[0][colIndex] = 0; + matrix[rowIndex][0] = 0; + } + } + } + + for (int rowIndex = 1; rowIndex < matrix.length; rowIndex++) { + for (int colIndex = 1; colIndex < matrix[0].length; colIndex++) { + if (matrix[0][colIndex] == 0 || matrix[rowIndex][0] == 0) { + matrix[rowIndex][colIndex] = 0; + } + } + } + + if (zeroExistsInTop) { + for (int colIndex=0; colIndex 두 방향으로 계속 뻗어가기 때문에 time complexity 가 (m+n)^2 까지 된다 흡 + * + * 2. dp 풀이 방법, 1차원 배열로 생각했을 때 dp배열의 인덱스는 인덱스만큼의 row, column 까지 도달하는 방법의 수를 계속해서 + * 누적해가는 방법으로 진행 + * + * @param m + * @param n + * @return + */ + public static int[][] vectors = {{0,1}, {1,0}}; + public int uniquePaths(int m, int n) { + // case 1. tle ㅠㅠ +// return dfs( 0, 0, m, n); + + // 뭔가 m*n 만큼의 배열이어야 할 것 같지만 사실 각 row마다의 column들에 방문할때의 방문 가능 갯수를 누적해가기때문에 n 만큼만 있어도 된다. + int[] dp = new int[n]; + + dp[0] = 1; // 시작점부터 path 가능 갯수 1 + for(int rowIdx = 0; rowIdx < m; rowIdx++) { + // 1부터 세는 이유는... 어차피 오른쪽으로 움직이기 때문예? + for(int colIdx = 1; colIdx < n; colIdx++) { + // dp[colIdx - 1] : 직전 column기준 0에서부터 도달할 수 있는 방법의 수 + // dp[colIdx] : rowIdx - 1이 었을때 0에서부터 [rowIdx - 1][colIdx] 까지 도달할 수 있는 방법의 수 + dp[colIdx] = dp[colIdx - 1] + dp[colIdx]; + } + } + + return dp[n - 1]; + } + +// public int dfs(int startRow, int startBottom, int m, int n) { +// if (startRow == m - 1 && startBottom == n - 1) { +// return 1; +// } else if (startRow >= m || startBottom >= n) { +// return 0; +// } +// +// int result = 0; +// +// for (int[] vector : vectors) { +// result += dfs(vector[1] + startRow, vector[0] + startBottom, m, n); +// } +// +// return result; +// } +} +