Skip to content

Commit f09e545

Browse files
committed
2 parents 6524b14 + e10ec05 commit f09e545

File tree

93 files changed

+3707
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+3707
-1
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: DaleStudy

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 DaleStudy
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
# Time Complexity: O(nlogn)
3+
# Space Complexity: O(nlogn)
4+
5+
*/
6+
class MedianFinder {
7+
8+
private PriorityQueue<Integer> pq1; // 1번째 ~ 가운데 원소 (max heap)
9+
private PriorityQueue<Integer> pq2; // 가운데+1번째 ~ 마지막 원소 (min heap)
10+
11+
public MedianFinder() {
12+
pq1 = new PriorityQueue<>(Collections.reverseOrder());
13+
pq2 = new PriorityQueue<>();
14+
}
15+
16+
public void addNum(int num) {
17+
18+
if (pq1.size() == pq2.size()) {
19+
if (pq1.peek() == null || pq1.peek() >= num) {
20+
pq1.add(num);
21+
} else {
22+
pq2.add(num);
23+
pq1.add(pq2.poll());
24+
}
25+
} else {
26+
if (pq1.peek() == null || pq1.peek() >= num) {
27+
pq1.add(num);
28+
pq2.add(pq1.poll());
29+
} else {
30+
pq2.add(num);
31+
}
32+
}
33+
}
34+
35+
public double findMedian() {
36+
if (pq1.size() == pq2.size()) {
37+
return (pq1.peek() + pq2.peek()) / 2.0;
38+
} else {
39+
return pq1.peek();
40+
}
41+
}
42+
}
43+
44+
/**
45+
* Your MedianFinder object will be instantiated and called as such:
46+
* MedianFinder obj = new MedianFinder();
47+
* obj.addNum(num);
48+
* double param_2 = obj.findMedian();
49+
*/
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// last test case failed
2+
// Time complexity: O(logn)
3+
// Space complexity: O(n)
4+
5+
class MinHeap {
6+
constructor() {
7+
this.heap = [null];
8+
}
9+
10+
get root() {
11+
if (this.length === 1) {
12+
return null;
13+
}
14+
15+
return this.heap[1];
16+
}
17+
18+
get length() {
19+
return this.heap.length;
20+
}
21+
22+
push(value) {
23+
this.heap.push(value);
24+
25+
let current = this.heap.length - 1;
26+
let parent = Math.floor(current / 2);
27+
28+
while (parent && this.heap[current] < this.heap[parent]) {
29+
[this.heap[current], this.heap[parent]] = [
30+
this.heap[parent],
31+
this.heap[current],
32+
];
33+
current = parent;
34+
parent = Math.floor(current / 2);
35+
}
36+
}
37+
38+
pop() {
39+
if (this.heap.length === 1) {
40+
return null;
41+
}
42+
43+
if (this.heap.length === 2) {
44+
return this.heap.pop();
45+
}
46+
47+
const rv = this.heap[1];
48+
this.heap[1] = this.heap.pop();
49+
50+
let current = 1;
51+
let left = current * 2;
52+
let right = left + 1;
53+
54+
while (
55+
(this.heap[left] && this.heap[current] > this.heap[left]) ||
56+
(this.heap[right] && this.heap[current] > this.heap[right])
57+
) {
58+
if (this.heap[right] && this.heap[right] < this.heap[left]) {
59+
[this.heap[right], this.heap[current]] = [
60+
this.heap[current],
61+
this.heap[right],
62+
];
63+
current = right;
64+
} else {
65+
[this.heap[left], this.heap[current]] = [
66+
this.heap[current],
67+
this.heap[left],
68+
];
69+
current = left;
70+
}
71+
72+
left = current * 2;
73+
right = left + 1;
74+
}
75+
76+
return rv;
77+
}
78+
}
79+
80+
var MedianFinder = function () {
81+
this.leftMinHeap = new MinHeap();
82+
this.rightMinHeap = new MinHeap();
83+
};
84+
85+
/**
86+
* @param {number} num
87+
* @return {void}
88+
*/
89+
MedianFinder.prototype.addNum = function (num) {
90+
const rightMinValue = this.rightMinHeap.root;
91+
92+
if (num >= rightMinValue) {
93+
this.rightMinHeap.push(num);
94+
} else {
95+
this.leftMinHeap.push(num * -1);
96+
}
97+
98+
if (this.rightMinHeap.length - this.leftMinHeap.length > 1) {
99+
const popped = this.rightMinHeap.pop();
100+
this.leftMinHeap.push(popped * -1);
101+
}
102+
103+
if (this.leftMinHeap.length - this.rightMinHeap.length > 1) {
104+
const popped = this.leftMinHeap.pop();
105+
this.rightMinHeap.push(popped * -1);
106+
}
107+
};
108+
109+
/**
110+
* @return {number}
111+
*/
112+
MedianFinder.prototype.findMedian = function () {
113+
const len = this.leftMinHeap.length + this.rightMinHeap.length;
114+
115+
if (len % 2 === 0) {
116+
return (this.leftMinHeap.root * -1 + this.rightMinHeap.root) / 2;
117+
}
118+
119+
if (this.leftMinHeap.length > this.rightMinHeap.length) {
120+
return this.leftMinHeap.root * -1;
121+
}
122+
123+
return this.rightMinHeap.root;
124+
};
125+
126+
/**
127+
* Your MedianFinder object will be instantiated and called as such:
128+
* var obj = new MedianFinder()
129+
* obj.addNum(num)
130+
* var param_2 = obj.findMedian()
131+
*/
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// 메모리초과로 알 수 있었던 것은 저장 공간이 여러개 필요하다는 거 였다.
2+
// 그리고 주어진 데이터가 정렬되지 않아서 무조건 nlog(n) 이상의 시간복잡도가 나오기 때문에
3+
// 자동 정렬할 수 있는 우선순위 큐를 사용하면 좋겠따고 생각
4+
// 그러나 데이터를 나누는 알고리즘이 필요한지 모르고 헤메다가 GPT 답을 보게됨
5+
// 시간복잡도 우선순위 큐 : O(logN)
6+
class MedianFinder {
7+
private PriorityQueue<Integer> maxHeap;
8+
private PriorityQueue<Integer> minHeap;
9+
10+
public MedianFinder() {
11+
maxHeap = new PriorityQueue<>(Collections.reverseOrder());
12+
minHeap = new PriorityQueue<>();
13+
}
14+
15+
public void addNum(int num) {
16+
maxHeap.offer(num);
17+
18+
if (!minHeap.isEmpty() && maxHeap.peek() > minHeap.peek()) {
19+
minHeap.offer(maxHeap.poll());
20+
}
21+
22+
if (maxHeap.size() > minHeap.size() + 1) {
23+
minHeap.offer(maxHeap.poll());
24+
} else if (minHeap.size() > maxHeap.size()) {
25+
maxHeap.offer(minHeap.poll());
26+
}
27+
}
28+
29+
public double findMedian() {
30+
if (maxHeap.size() > minHeap.size()) {
31+
return maxHeap.peek();
32+
} else {
33+
return (maxHeap.peek() + minHeap.peek()) / 2.0;
34+
}
35+
}
36+
}
37+
38+
// 메모리초과
39+
class MedianFinder {
40+
private List<Integer> arr;
41+
42+
public MedianFinder() {
43+
arr = new ArrayList<>();
44+
}
45+
46+
public void addNum(int num) {
47+
arr.add(num);
48+
}
49+
50+
public double findMedian() {
51+
Collections.sort(arr);
52+
53+
int size = arr.size();
54+
if (size % 2 == 1) {
55+
return arr.get(size / 2);
56+
} else {
57+
return (arr.get(size / 2 - 1) + arr.get(size / 2)) / 2.0;
58+
}
59+
}
60+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Time Complexity:
2+
# - addNum(): O(log N) - use a heap operation (push/pop) which takes log N time.
3+
# - findMedian(): O(1) - just accessing the top elements of heaps.
4+
# Space Complexity: O(N) - store all elements in two heaps.
5+
6+
7+
class MedianFinder:
8+
def __init__(self):
9+
# max heap (stores the smaller half of numbers, negated values for max heap behavior)
10+
self.maxHeap = []
11+
# min heap (stores the larger half of numbers)
12+
self.minHeap = []
13+
14+
def addNum(self, num: int) -> None:
15+
if not self.maxHeap or num <= -self.maxHeap[0]:
16+
# store as negative to simulate max heap
17+
heapq.heappush(self.maxHeap, -num)
18+
else:
19+
heapq.heappush(self.minHeap, num)
20+
21+
# balance the heaps: maxHeap can have at most 1 more element than minHeap
22+
if len(self.maxHeap) > len(self.minHeap) + 1:
23+
heapq.heappush(self.minHeap, -heapq.heappop(self.maxHeap))
24+
elif len(self.minHeap) > len(self.maxHeap):
25+
heapq.heappush(self.maxHeap, -heapq.heappop(self.minHeap))
26+
27+
def findMedian(self) -> float:
28+
if len(self.maxHeap) > len(self.minHeap):
29+
return -self.maxHeap[0] # odd number of elements, maxHeap has the median
30+
else:
31+
return (-self.maxHeap[0] + self.minHeap[0]) / 2.0 # even case, average of two middle numbers

insert-interval/KwonNayeon.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""
2+
Constraints:
3+
- 0 <= intervals.length <= 10^4
4+
- intervals[i].length == 2
5+
- 0 <= starti <= endi <= 10^5
6+
- intervals is sorted by starti in ascending order.
7+
- newInterval.length == 2
8+
- 0 <= start <= end <= 10^5
9+
10+
Time Complexity: O(n)
11+
- 모든 interval을 한 번씩만 처리함
12+
13+
Space Complexity: O(n)
14+
- 최악의 경우 모든 interval을 결과 리스트에 저장
15+
16+
풀이방법:
17+
1. 세 단계로 구분하여 처리:
18+
- Step 1: newInterval보다 앞에 있는 intervals → 결과에 바로 추가
19+
- Step 2: newInterval과 겹치는 intervals → 병합하여 하나의 interval로 만듦
20+
- Step 3: newInterval보다 뒤에 있는 intervals → 결과에 바로 추가
21+
2. 병합 조건:
22+
- 두 interval이 겹치는 조건: intervals[i][0] <= mergedInterval[1]
23+
- 병합 시 시작점: min(mergedInterval[0], intervals[i][0])
24+
- 병합 시 끝점: max(mergedInterval[1], intervals[i][1])
25+
26+
노트:
27+
- 세 단계로 구분하여 처리하는 게 쉽지 않았다. 다음에 풀 땐 스스로 해결해볼 것
28+
"""
29+
class Solution:
30+
def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
31+
result = []
32+
i = 0
33+
n = len(intervals)
34+
35+
while i < n and intervals[i][1] < newInterval[0]:
36+
result.append(intervals[i])
37+
i += 1
38+
39+
merged_interval = newInterval
40+
while i < n and intervals[i][0] <= merged_interval[1]:
41+
merged_interval[0] = min(merged_interval[0], intervals[i][0])
42+
merged_interval[1] = max(merged_interval[1], intervals[i][1])
43+
i += 1
44+
result.append(merged_interval)
45+
46+
while i < n:
47+
result.append(intervals[i])
48+
i += 1
49+
50+
return result

insert-interval/YeomChaeeun.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* 중간에 새로운 구간 추가하기
3+
* 알고리즘 복잡도
4+
* - 시간 복잡도: O(n)
5+
* - 공간 복잡도: O(n)
6+
* @param intervals
7+
* @param newInterval
8+
*/
9+
function insert(intervals: number[][], newInterval: number[]): number[][] {
10+
if(intervals.length === 0) return [newInterval]
11+
let result: number[][] = []
12+
13+
let i = 0;
14+
15+
// 1. newIntervals 이전 구간 추가
16+
while(i < intervals.length && intervals[i][1] < newInterval[0]) {
17+
result.push(intervals[i])
18+
i++
19+
}
20+
21+
// 2. 겹치는 부분 추가
22+
const merged = [...newInterval]
23+
while(i < intervals.length && intervals[i][0] <= newInterval[1]) {
24+
merged[0] = Math.min(merged[0], intervals[i][0])
25+
merged[1] = Math.max(merged[1], intervals[i][1])
26+
i++
27+
}
28+
result.push(merged)
29+
30+
// 3. 이후의 구간 추가
31+
while(i < intervals.length) {
32+
result.push(intervals[i])
33+
i++
34+
}
35+
36+
return result
37+
}
38+

0 commit comments

Comments
 (0)