diff --git a/find-median-from-data-stream/crumbs22.cpp b/find-median-from-data-stream/crumbs22.cpp new file mode 100644 index 000000000..9946d2c82 --- /dev/null +++ b/find-median-from-data-stream/crumbs22.cpp @@ -0,0 +1,39 @@ +/* + minHeap이 항상 maxHeap보다 크거나 같도록 유지한다. + addNum() + - maxHeap에 새로 들어온 num을 포함한 최댓값을 minHeap으로 옮긴다 + - 처음엔 maxHeap과 minHeap의 크기 차이가 1이므로 if문에 들어가지 않지만 + - 이후 num이 minHeap으로 하나 더 넘어가게 되면 maxHeap과 minHeap의 크기 차이가 2가 되므로 + if문에 들어가서 maxHeap쪽으로 minHeap의 최솟값을 옮긴다 + 힙 삽입에 O(logn)이 걸리므로 시간복잡도는 O(logn)이다 + findMedian() + - 두 힙의 top만 참조하면 되므로 시간 복잡도는 O(1)이다 + 최소힙과 최대힙은 각각 전체 수의 절반씩을 저장한다. + 공간 복잡도는 O(n)이다 +*/ +class MedianFinder { +public: + priority_queue maxHeap; + priority_queue, greater> minHeap; + + MedianFinder() { + } + + void addNum(int num) { + maxHeap.push(num); + + minHeap.push(maxHeap.top()); + maxHeap.pop(); + + if (maxHeap.size() + 1 < minHeap.size()) { + maxHeap.push(minHeap.top()); + minHeap.pop(); + } + } + + double findMedian() { + if (maxHeap.size() == minHeap.size()) + return (minHeap.top() + maxHeap.top()) / 2.0; + return minHeap.top(); + } +}; diff --git a/insert-interval/crumbs22.cpp b/insert-interval/crumbs22.cpp new file mode 100644 index 000000000..137c93bf9 --- /dev/null +++ b/insert-interval/crumbs22.cpp @@ -0,0 +1,28 @@ +class Solution { +public: + vector> insert(vector>& intervals, vector& newInterval) { + vector> res; + int i = 0; + + // 겹치지 않을 때 res 벡터에 intervals를 그대로 삽입 + while (i < intervals.size() && intervals[i][1] < newInterval[0]) { + res.push_back(intervals[i]); + i++; + } + + // 겹치는 동안 반복하며 시작지점과 끝지점 갱신 + while (i < intervals.size() && intervals[i][0] <= newInterval[1]) { + newInterval[0] = min(intervals[i][0], newInterval[0]); + newInterval[1] = max(newInterval[1], intervals[i][1]); + i++; + } + res.push_back(newInterval); // 삽입 + + // 남은 벡터 마저 삽입 + while (i < intervals.size()) { + res.push_back(intervals[i]); + i++; + } + return (res); + } +}; diff --git a/kth-smallest-element-in-a-bst/crumbs22.cpp b/kth-smallest-element-in-a-bst/crumbs22.cpp new file mode 100644 index 000000000..a519be3c2 --- /dev/null +++ b/kth-smallest-element-in-a-bst/crumbs22.cpp @@ -0,0 +1,29 @@ +/* + dfs로 트리 탐색하며 k번째로 작은 값을 찾음 + 왼쪽서브트리-> 루트 -> 오른쪽 서브트리 순으로 탐색 (중위순회) + 왼쪽 서브트리를 먼저 탐색함 (값이 작은 순으로 탐색하기 위함) + - 왼쪽이 없으면 return -1 + - 현재 노드 방문 -> k를 1 감소 + - 오른쪽도 같은 방식으로 탐색 + - 자식에서 -1을 반환 받았을 때에는 k번째 작은 값을 찾지 못한 상태로, k값을 줄이며 계속 탐색 + - 자식에서 -1이 아닌 값을 반환 받았을 때에는 k번째 작은 값을 찾은 상태로, 해당 값을 계속적으로 반환 +*/ +class Solution { +public: + int kthSmallest(TreeNode* root, int k) { + return (dfs(root, k)); + } + + int dfs(TreeNode* root, int &k) { + if (!root) + return -1; + + int l = dfs(root->left, k); + if (l != -1) + return l; + k--; + if (k == 0) // 현재 노드가 k번째로 작은 값일 때 + return root->val; + return dfs(root->right, k); + } +}; diff --git a/lowest-common-ancestor-of-a-binary-search-tree/crumbs22.cpp b/lowest-common-ancestor-of-a-binary-search-tree/crumbs22.cpp new file mode 100644 index 000000000..25709a9bc --- /dev/null +++ b/lowest-common-ancestor-of-a-binary-search-tree/crumbs22.cpp @@ -0,0 +1,26 @@ +/* + p와 q의 공통조상을 찾는 문제 + 왼쪽과 오른쪽에서 각각 p와 q를 찾고, 만약 좌우에서 모두 p와 q를 찾았다면 현재 노드가 공통 조상이다 + p와 q 중 하나만 존재한다면 존재하는 쪽의 노드에 공통조상이 존재한다 + 모든 노드를 한번씩 방문하므로 시간복잡도는 O(n)이다. 공간복잡도는 트리의 높이에 비례하므로 O(h). +*/ +class Solution { +public: + TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { + if (!root) + return nullptr; + if (root->val == p->val) + return p; + if (root->val == q->val) + return q; + + TreeNode* nl = lowestCommonAncestor(root->left, p, q); + TreeNode* nr = lowestCommonAncestor(root->right, p, q); + if (!nl && nr) // nl쪽이 비어있으면 nr쪽에 공통조상 존재 + return nr; + else if (!nr) // nr쪽이 비어있으면 nl쪽에 공통조상 존재 + return nl; + else // 그 외의 경우는 nr과 nl의 부모에 공통조상 존재 + return root; + } +}; diff --git a/meeting-rooms/crumbs22.cpp b/meeting-rooms/crumbs22.cpp new file mode 100644 index 000000000..26a775f59 --- /dev/null +++ b/meeting-rooms/crumbs22.cpp @@ -0,0 +1,21 @@ +class Solution { +public: + /** + * @param intervals: an array of meeting time intervals + * @return: if a person could attend all meetings + */ + bool canAttendMeetings(vector &intervals) { + // 시작 시간 기준으로 정렬 + sort(intervals.begin(), intervals.end(), [](const Interval &a, const Interval &b) { + return a.start < b.start; + }); + + // 시작시간과 끝시간을 비교해서 겹치면 false 반환 + for (int i = 1; i < intervals.size(); i++) { + if (intervals[i].start < intervals[i - 1].end) { + return false; + } + } + return true; + } +};