Skip to content

Commit 499d198

Browse files
authored
[ PS ] : Find Median from Data Stream
1 parent f45d2fb commit 499d198

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// 배열 + 이분 탐색 삽입 (정렬) 로 풀이함
2+
3+
// 다른 방식으로는 듀얼 힙을 사용하는 게 있음 (성능 면에서 더 우수함)
4+
// 최소힙, 최대힙 두 개를 두고 나눠서 add 이 때 size 차이는 1 이하여야 함
5+
// ex. 1 2 3 4 5 6 => 최대 힙에 1 2 3, 최소 힙에 4 5 6 => (3 + 4) / 2
6+
// ex. 2 3 4 => 최대 힙에 2 3, 최소 힙에 4 => 3
7+
// 참고로 leetcode에서 JS를 위한 MaxPriorityQueue와 같은 자료구조를 제공하는 듯 한데...
8+
// 메서드를 어디서 볼 수 있는지 모르겠음
9+
10+
class MedianFinder {
11+
constructor() {
12+
this.nums = [];
13+
}
14+
15+
/**
16+
* 시간복잡도: O(n) (이분탐색: log n, splice: n)
17+
* 공간복잡도: O(1)
18+
* @param {number} num
19+
* @return {void}
20+
*/
21+
addNum(num) {
22+
const i = this.#findInsertPosition(num);
23+
this.nums.splice(i, 0, num);
24+
}
25+
26+
/**
27+
* 이진 탐색으로 삽입 지점 찾는 함수
28+
* 시간복잡도: O(log n)
29+
* 공간복잡도: O(1)
30+
*/
31+
#findInsertPosition(num) {
32+
let left = 0;
33+
let right = this.nums.length;
34+
35+
while (left <= right) {
36+
const mid = Math.floor((left + right) / 2);
37+
38+
if (num < this.nums[mid]) {
39+
right = mid - 1;
40+
} else if (this.nums[mid] < num) {
41+
left = mid + 1;
42+
} else {
43+
return mid;
44+
}
45+
}
46+
47+
return left;
48+
}
49+
50+
/**
51+
* 시간복잡도: O(1)
52+
* 공간복잡도: O(1)
53+
* @return {number}
54+
*/
55+
findMedian() {
56+
const len = this.nums.length;
57+
const midIndex = Math.floor(len / 2);
58+
59+
if (len % 2 === 0) {
60+
return (this.nums[midIndex - 1] + this.nums[midIndex]) / 2;
61+
} else {
62+
return this.nums[midIndex];
63+
}
64+
}
65+
};
66+
67+
/**
68+
* Your MedianFinder object will be instantiated and called as such:
69+
* var obj = new MedianFinder()
70+
* obj.addNum(num)
71+
* var param_2 = obj.findMedian()
72+
*/

0 commit comments

Comments
 (0)