Skip to content

[hyunjung-choi] WEEK 04 solutions #1813

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions coin-change/hyunjung-choi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* 시간복잡도: O(amount × coins.length)
* 공간복잡도: O(amount)
*/

class Solution {
fun coinChange(coins: IntArray, amount: Int): Int {
val dp = IntArray(amount + 1) { Int.MAX_VALUE }
dp[0] = 0

for (i in 1..amount) {
for (coin in coins) {
if (i - coin >= 0 && dp[i - coin] != Int.MAX_VALUE) {
dp[i] = minOf(dp[i], dp[i - coin] + 1)
}
}
}

return if (dp[amount] == Int.MAX_VALUE) -1 else dp[amount]
}
}
26 changes: 26 additions & 0 deletions find-minimum-in-rotated-sorted-array/hyunjung-choi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 시간 복잡도: O(log n)
// - n: 배열의 길이
// - 매 반복마다 탐색 범위를 절반으로 줄이는 이진 탐색이므로 O(log n)
//
// 공간 복잡도: O(1)
// - 추가적인 배열이나 자료구조를 사용하지 않고,
// 변수(left, right, mid)만 사용하므로 상수 공간

class Solution {
fun findMin(nums: IntArray): Int {
var left = 0
var right = nums.size - 1

while (left < right) {
val mid = left + (right - left) / 2

if (nums[mid] > nums[right]) {
left = mid + 1
} else {
right = mid
}
}

return nums[left]
}
}
20 changes: 20 additions & 0 deletions maximum-depth-of-binary-tree/hyunjung-choi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// 시간 복잡도: O(n)
// - n: 트리의 노드 개수
// - 각 노드를 정확히 한 번씩 방문하므로 O(n)
//
// 공간 복잡도: O(h)
// - h: 트리의 높이
// - 재귀 호출 스택에 최대 h개의 함수 호출이 쌓임
// - 최악의 경우(편향 트리) h = n 이므로 O(n),
// 최선의 경우(균형 트리) h = log n 이므로 O(log n)

class Solution {
fun maxDepth(root: TreeNode?): Int {
if (root == null) return 0

val leftDepth = maxDepth(root.left)
val rightDepth = maxDepth(root.right)

return maxOf(leftDepth, rightDepth) + 1
}
}
33 changes: 33 additions & 0 deletions merge-two-sorted-lists/hyunjung-choi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// 시간 복잡도: O(n + m)
// - n: list1의 길이, m: list2의 길이
// - 두 리스트를 한 번씩만 순회하며 병합하므로 O(n + m)
//
// 공간 복잡도: O(1)
// - 주어진 노드들을 재사용하여 병합하고, 추가로 더미 노드(dummy) 하나만 사용
// - 재귀 호출 없이 포인터만 이동하므로 상수 공간만 필요

class Solution {
fun mergeTwoLists(list1: ListNode?, list2: ListNode?): ListNode? {
val dummy = ListNode(0)
var current = dummy

var p1 = list1
var p2 = list2

while (p1 != null && p2 != null) {
if (p1.`val` >= p2.`val`) {
current.next = p2
p2 = p2.next
} else {
current.next = p1
p1 = p1.next
}

current = current.next!!
}

current.next = p1 ?: p2

return dummy.next
}
}
39 changes: 39 additions & 0 deletions word-search/hyunjung-choi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 시간 복잡도 (R=행, C=열, N=R*C, L=word.length)
* - 모든 칸(N개)에서 시작 가능.
* - DFS 한 단계에서 최대 4방향, 다음 단계부터는 되돌아갈 수 없으므로 최대 3방향으로 분기.
* - 최악: N * (4 * 3^(L-1)) = O(R*C*3^L).
*
* 공간 복잡도
* - visited 배열: O(R*C)
* - 재귀 콜스택: 경로 길이 최대 L → O(L)
* - 총합: O(R*C + L) (최악 기준은 O(R*C))
*/

class Solution {
fun exist(board: Array<CharArray>, word: String): Boolean {
if (word.isEmpty()) return true

val rows = board.size
val cols = board.firstOrNull()?.size ?: return false
val visited = Array(rows) { BooleanArray(cols) }
val directions = arrayOf(1 to 0, -1 to 0, 0 to 1, 0 to -1)

fun dfs(r: Int, c: Int, index: Int): Boolean {
if (index == word.length) return true
if (r !in 0 until rows || c !in 0 until cols) return false
if (visited[r][c] || board[r][c] != word[index]) return false

visited[r][c] = true
val found = directions.any { (dr, dc) -> dfs(r + dr, c + dc, index + 1) }
visited[r][c] = false
return found
}

return board.indices.any { r ->
board[0].indices.any { c ->
board[r][c] == word[0] && dfs(r, c, 0)
}
}
}
}