diff --git a/set-matrix-zeroes/jdalma.kt b/set-matrix-zeroes/jdalma.kt new file mode 100644 index 000000000..477969ccc --- /dev/null +++ b/set-matrix-zeroes/jdalma.kt @@ -0,0 +1,111 @@ +package leetcode_study + +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test +import kotlin.math.max + +class `set-matrix-zeroes` { + + private data class Position( + val x: Int, + val y: Int + ) + + fun setZeroes(matrix: Array): Unit { + usingFlag(matrix) + } + + /** + * 0으로 변경해야 할 열과 행을 Set에 담아 처리한다. + * TC: O(n * m) SC: O(n + m) + */ + private fun usingSet(matrix: Array) { + val zeroRows = mutableSetOf() + val zeroCols = mutableSetOf() + for (i in matrix.indices) { + for (j in matrix.first().indices) { + if (matrix[i][j] == 0) { + zeroRows.add(i) + zeroCols.add(j) + } + } + } + + for (row in zeroRows) { + for (col in matrix.first().indices) { + matrix[row][col] = 0 + } + } + + for (col in zeroCols) { + for (row in matrix.indices) { + matrix[row][col] = 0 + } + } + } + + /** + * 0으로 변경해야 할 열과 행을 matrix 0번째 행과 0번째 열 그리고 두 개의 flag로 처리하여 공간복잡도를 개선한다. + * TC: O(n * m) SC: O(1) + */ + private fun usingFlag(matrix: Array) { + var (rowFlag, colFlag) = false to false + for (i in matrix.indices) { + for (j in matrix.first().indices) { + if (matrix[i][j] == 0) { + if (i == 0) rowFlag = true + if (j == 0) colFlag = true + matrix[0][j] = 0 + matrix[i][0] = 0 + } + } + } + + for (i in 1 until matrix.size) { + for (j in 1 until matrix.first().size) { + if (matrix[i][0] == 0 || matrix[0][j] == 0) { + matrix[i][j] = 0 + } + } + } + + if (rowFlag) { + for (i in matrix.first().indices) { + matrix[0][i] = 0 + } + } + + if (colFlag) { + for (element in matrix) { + element[0] = 0 + } + } + } + + @Test + fun `원소가 0이라면 해당 행과 열을 모두 0으로 수정한다`() { + val actual1 = arrayOf( + intArrayOf(1,1,1), + intArrayOf(1,0,1), + intArrayOf(1,1,1) + ) + setZeroes(actual1) + actual1 shouldBe arrayOf( + intArrayOf(1,0,1), + intArrayOf(0,0,0), + intArrayOf(1,0,1) + ) + + val actual2 = arrayOf( + intArrayOf(0,1,2,0), + intArrayOf(3,4,5,2), + intArrayOf(1,3,1,5) + ) + setZeroes(actual2) + actual2 shouldBe arrayOf( + intArrayOf(0,0,0,0), + intArrayOf(0,4,5,0), + intArrayOf(0,3,1,0) + ) + } +} diff --git a/unique-paths/jdalma.kt b/unique-paths/jdalma.kt new file mode 100644 index 000000000..53ecda265 --- /dev/null +++ b/unique-paths/jdalma.kt @@ -0,0 +1,58 @@ +package leetcode_study + +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test + +/** + * 0,0 에서 아래 또는 오른쪽으로만 이동 가능하다. + */ +class `unique-paths` { + + fun uniquePaths(row: Int, col: Int): Int { + return if (row <= 1 || col <= 1) 1 + else usingArray(row, col) + } + + /** + * TC: O(n * m), SC: O(n * m) + */ + private fun usingGrid(row: Int, col: Int): Int { + val grid = Array(row) { IntArray(col) } + (0 until row).forEach { grid[it][0] = 1 } + (0 until col).forEach { grid[0][it] = 1 } + + for (i in 1 until row) { + for (j in 1 until col) { + grid[i][j] = grid[i - 1][j] + grid[i][j - 1] + } + } + + return grid[row - 1][col - 1] + } + + /** + * 이전 라인의 배열만 기억하여도 되므로 공간 복잡도를 아래와 같이 줄일 수 있다. + * TC: O(n * m), SC: O(m) + */ + private fun usingArray(row: Int, col: Int): Int { + var dp = IntArray(col) + + for (i in 0 until row) { + val tmp = IntArray(col) + for (j in 0 until col) { + if (i == 0 && j == 0) tmp[j] = 1 + else if (j > 0) tmp[j] = dp[j] + tmp[j - 1] + else tmp[j] = dp[j] + } + dp = tmp + } + + return dp.last() + } + + @Test + fun `왼쪽 상단 모서리에서 오른쪽 상단 모서리로 도달할 수 있는 고유 경로의 수를 반환한다`() { + uniquePaths(3, 7) shouldBe 28 + uniquePaths(3, 2) shouldBe 3 + } +}