Skip to content

Commit 7444507

Browse files
committed
마지막 문제 추가
1 parent b1dfe9e commit 7444507

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed

merge-k-sorted-lists/jdalma.kt

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package leetcode_study
2+
3+
import io.kotest.matchers.shouldBe
4+
import org.junit.jupiter.api.Test
5+
import java.lang.RuntimeException
6+
7+
class `merge-k-sorted-lists` {
8+
9+
data class ListNode(var `val`: Int) {
10+
var next: ListNode? = null
11+
12+
companion object {
13+
fun of(vararg `val`: Int): ListNode {
14+
val dummy = ListNode(-1)
15+
var prev = dummy
16+
for (v in `val`) {
17+
prev.next = ListNode(v)
18+
prev = prev.next ?: throw RuntimeException()
19+
}
20+
return dummy.next ?: throw RuntimeException()
21+
}
22+
}
23+
}
24+
25+
fun mergeKLists(lists: Array<ListNode?>): ListNode? {
26+
return if (lists.isEmpty()) null
27+
else if (lists.size == 1) lists.first()
28+
else mergeDivideAndConquer(lists)
29+
}
30+
31+
/**
32+
* TC: O(lists.size * ListNode.size), SC: O(1)
33+
*/
34+
private fun usingBruteForce(lists: Array<ListNode?>): ListNode? {
35+
val dummy = ListNode(-1)
36+
var prev = dummy
37+
38+
while (true) {
39+
var minNode: ListNode? = null
40+
var minIndex = -1
41+
42+
for (index in lists.indices) {
43+
val curr = lists[index] ?: continue
44+
if (minNode == null || curr.`val` < minNode.`val`) {
45+
minNode = curr
46+
minIndex = index
47+
}
48+
}
49+
prev.next = minNode ?: break
50+
prev = prev.next ?: throw RuntimeException()
51+
52+
lists[minIndex] = minNode.next
53+
}
54+
55+
return dummy.next
56+
}
57+
58+
/**
59+
* TC: O(lists.size * ListNode.size), SC: O(1)
60+
*/
61+
private fun mergeLists(lists: Array<ListNode?>): ListNode? {
62+
fun merge(node1: ListNode?, node2: ListNode?): ListNode? {
63+
val dummy = ListNode(-1)
64+
var prev = dummy
65+
var (n1, n2) = node1 to node2
66+
while (n1 != null && n2 != null) {
67+
if (n1.`val` < n2.`val`) {
68+
prev.next = n1
69+
n1 = n1.next
70+
} else {
71+
prev.next = n2
72+
n2 = n2.next
73+
}
74+
prev.next?.let { prev = it }
75+
}
76+
prev.next = n1 ?: n2
77+
return dummy.next
78+
}
79+
for (index in 1 until lists.size) {
80+
lists[0] = merge(lists[0], lists[index])
81+
}
82+
return lists[0]
83+
}
84+
85+
/**
86+
* TC: O(lists.size * ListNode.size), SC: O(lists.size)
87+
*/
88+
private fun mergeDivideAndConquer(lists: Array<ListNode?>): ListNode? {
89+
fun merge(node1: ListNode?, node2: ListNode?): ListNode? {
90+
val dummy = ListNode(-1)
91+
var prev = dummy
92+
var (n1, n2) = node1 to node2
93+
while (n1 != null && n2 != null) {
94+
if (n1.`val` < n2.`val`) {
95+
prev.next = n1
96+
n1 = n1.next
97+
} else {
98+
prev.next = n2
99+
n2 = n2.next
100+
}
101+
prev.next?.let { prev = it }
102+
}
103+
prev.next = n1 ?: n2
104+
return dummy.next
105+
}
106+
107+
fun divideAndConquer(lists: Array<ListNode?>, s: Int, e: Int): ListNode? {
108+
if (s > e) return null
109+
else if (s == e) return lists[s]
110+
111+
val mid = (s + e) / 2
112+
val left = divideAndConquer(lists, s, mid)
113+
val right = divideAndConquer(lists, mid + 1, e)
114+
return merge(left, right)
115+
}
116+
117+
return divideAndConquer(lists, 0, lists.size - 1)
118+
}
119+
120+
@Test
121+
fun `전달받은 노드들을 정렬하고 병합된 결과를 반환한다`() {
122+
mergeKLists(
123+
arrayOf(
124+
ListNode.of(1,4,5),
125+
ListNode.of(1,3,4),
126+
ListNode.of(2,6)
127+
)
128+
) shouldBe ListNode.of(1,1,2,3,4,4,5,6)
129+
}
130+
}

0 commit comments

Comments
 (0)