Skip to content

Commit 8c9dd17

Browse files
committed
Solution: Merge K Sorted Lists
1 parent 92fb01e commit 8c9dd17

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

merge-k-sorted-lists/flynn.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
풀이 1
3+
- lists를 순회하면서 순서대로 링크드리스트 두 개를 짝 지어 병합하는 방식으로 풀이할 수 있습니다
4+
5+
Big O
6+
- K: 배열 lists의 길이
7+
- N: 모든 링크드리스트의 노드 개수의 합
8+
- n_i: i번 인덱스 링크드리스트의 노드의 개수
9+
- Time complexity: O(KN)
10+
- K-1 번의 병합을 진행합니다
11+
- i번째 병합 때, 병합하는 두 링크드리스트는 각각 𝚺(n_(i-1)), n_i입니다
12+
이 때 𝚺(n_(i-1))의 상한을 고려한다면 두 링크드리스트의 병합에 걸리는 시간복잡도는 O(N)입니다
13+
- O((K-1)N) = O(KN)
14+
- 풀이 2로 시간복잡도를 O((logK)N)으로 최적화할 수 있습니다
15+
- Space complexity: O(1)
16+
- res, dummy, curr 등의 추가적인 포인터를 생성하긴 하지만 기존에 주어져 있던 ListNode의 Next만 조작하므로 K, N과 상관 없이 공간복잡도는 상수값을 가집니다
17+
*/
18+
19+
/**
20+
* Definition for singly-linked list.
21+
* type ListNode struct {
22+
* Val int
23+
* Next *ListNode
24+
* }
25+
*/
26+
func mergeKLists(lists []*ListNode) *ListNode {
27+
n := len(lists)
28+
29+
if n == 0 {
30+
return nil
31+
}
32+
33+
res := lists[0]
34+
for i := 1; i < n; i++ {
35+
res = mergeTwoLists(res, lists[i])
36+
}
37+
return res
38+
}
39+
40+
func mergeTwoLists(first *ListNode, second *ListNode) *ListNode {
41+
dummy := &ListNode{}
42+
curr := dummy
43+
44+
for first != nil && second != nil {
45+
if first.Val < second.Val {
46+
curr.Next = first
47+
first = first.Next
48+
} else {
49+
curr.Next = second
50+
second = second.Next
51+
}
52+
curr = curr.Next
53+
}
54+
55+
if first != nil {
56+
curr.Next = first
57+
}
58+
if second != nil {
59+
curr.Next = second
60+
}
61+
62+
return dummy.Next
63+
}
64+
65+
66+
/*
67+
풀이 2
68+
- Divide and Conquer 방식으로 시간복잡도를 최적화할 수 있습니다
69+
- 하지만 공간복잡도 측면에서는 trade-off가 있습니다
70+
71+
Big O
72+
- K: 배열 lists의 길이
73+
- N: 모든 링크드리스트의 노드 개수의 합
74+
- Time complexity: O((logK)N)
75+
- lists를 반으로 쪼개 가면서 재귀호출을 진행하므로 재귀호출은 logK 레벨에 걸쳐 이루어집니다 -> O(logK)
76+
- 각 계층마다 우리는 모든 노드를 최대 한 번씩 조회합니다 -> O(N)
77+
- Space complexity: O(logK)
78+
- 풀이 1과 비슷하지만 재귀호출 스택을 고려해야 합니다
79+
*/
80+
81+
/**
82+
* Definition for singly-linked list.
83+
* type ListNode struct {
84+
* Val int
85+
* Next *ListNode
86+
* }
87+
*/
88+
func mergeKLists(lists []*ListNode) *ListNode {
89+
n := len(lists)
90+
91+
if n == 0 {
92+
return nil
93+
}
94+
if n == 1 {
95+
return lists[0]
96+
}
97+
98+
left := mergeKLists(lists[:n/2])
99+
right := mergeKLists(lists[n/2:])
100+
101+
return mergeTwoLists(left, right)
102+
}
103+
104+
func mergeTwoLists(first *ListNode, second *ListNode) *ListNode {
105+
dummy := &ListNode{}
106+
curr := dummy
107+
108+
for first != nil && second != nil {
109+
if first.Val < second.Val {
110+
curr.Next = first
111+
first = first.Next
112+
} else {
113+
curr.Next = second
114+
second = second.Next
115+
}
116+
curr = curr.Next
117+
}
118+
119+
if first != nil {
120+
curr.Next = first
121+
}
122+
if second != nil {
123+
curr.Next = second
124+
}
125+
126+
return dummy.Next
127+
}

0 commit comments

Comments
 (0)