From 4303b04b8d1ae64e166bed1527ca64f5266f4cf9 Mon Sep 17 00:00:00 2001 From: Ju Hwijung Date: Sat, 30 May 2026 12:39:07 +0900 Subject: [PATCH 1/2] =?UTF-8?q?13=EC=A3=BC=EC=B0=A8=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=ED=92=80=EC=9D=B4=205=EA=B0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- find-median-from-data-stream/hwi-middle.cpp | 32 ++++++++++++++ insert-interval/hwi-middle.cpp | 30 +++++++++++++ kth-smallest-element-in-a-bst/hwi-middle.cpp | 44 +++++++++++++++++++ .../hwi-middle.cpp | 22 ++++++++++ meeting-rooms/hwi-middle.cpp | 20 +++++++++ 5 files changed, 148 insertions(+) create mode 100644 find-median-from-data-stream/hwi-middle.cpp create mode 100644 insert-interval/hwi-middle.cpp create mode 100644 kth-smallest-element-in-a-bst/hwi-middle.cpp create mode 100644 lowest-common-ancestor-of-a-binary-search-tree/hwi-middle.cpp create mode 100644 meeting-rooms/hwi-middle.cpp diff --git a/find-median-from-data-stream/hwi-middle.cpp b/find-median-from-data-stream/hwi-middle.cpp new file mode 100644 index 0000000000..bf6a9b7e34 --- /dev/null +++ b/find-median-from-data-stream/hwi-middle.cpp @@ -0,0 +1,32 @@ +class MedianFinder { +public: + MedianFinder() { + } + + void addNum(int num) { + maxHeap.push(num); + minHeap.push(maxHeap.top()); + maxHeap.pop(); + + if (maxHeap.size() < minHeap.size()) + { + maxHeap.push(minHeap.top()); + minHeap.pop(); + } + } + + double findMedian() { + return maxHeap.size() > minHeap.size() ? maxHeap.top() : ((double) maxHeap.top() + minHeap.top()) * 0.5; + } + +private: + priority_queue maxHeap; + priority_queue, greater> minHeap; +}; + +/** + * Your MedianFinder object will be instantiated and called as such: + * MedianFinder* obj = new MedianFinder(); + * obj->addNum(num); + * double param_2 = obj->findMedian(); + */ diff --git a/insert-interval/hwi-middle.cpp b/insert-interval/hwi-middle.cpp new file mode 100644 index 0000000000..e810a58d30 --- /dev/null +++ b/insert-interval/hwi-middle.cpp @@ -0,0 +1,30 @@ +class Solution { +public: + vector> insert(vector>& intervals, vector& newInterval) { + int n = intervals.size(); + vector> res; + + int i = 0; + while (i < n && intervals[i][1] < newInterval[0]) + { + res.push_back(intervals[i]); + i++; + } + + while (i < n && newInterval[1] >= intervals[i][0]) + { + newInterval[0] = min(newInterval[0], intervals[i][0]); + newInterval[1] = max(newInterval[1], intervals[i][1]); + i++; + } + res.push_back(newInterval); + + while (i < n) + { + res.push_back(intervals[i]); + i++; + } + + return res; + } +}; diff --git a/kth-smallest-element-in-a-bst/hwi-middle.cpp b/kth-smallest-element-in-a-bst/hwi-middle.cpp new file mode 100644 index 0000000000..ad0712fca5 --- /dev/null +++ b/kth-smallest-element-in-a-bst/hwi-middle.cpp @@ -0,0 +1,44 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + int kthSmallest(TreeNode* root, int k) { + int cur = 0; + return impl(root, k, cur); + } + + int impl(TreeNode* root, int k, int& cur) { + if (root == nullptr) + { + return -1; + } + + int l = impl(root->left, k, cur); + if (l != -1) + { + return l; + } + + if (++cur == k) + { + return root->val; + } + + int r = impl(root->right, k, cur); + if (r != -1) + { + return r; + } + + return -1; + } +}; diff --git a/lowest-common-ancestor-of-a-binary-search-tree/hwi-middle.cpp b/lowest-common-ancestor-of-a-binary-search-tree/hwi-middle.cpp new file mode 100644 index 0000000000..8654d0d33c --- /dev/null +++ b/lowest-common-ancestor-of-a-binary-search-tree/hwi-middle.cpp @@ -0,0 +1,22 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ + +class Solution { +public: + TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { + // p와 q가 root 기준 왼쪽과 오른쪽에 나뉘어 존재하면 root가 LCA + while ((root->val - p->val) * (long long)(root->val - q->val) > 0LL) + { + root = root->val > p->val ? root->left : root->right; + } + + return root; + } +}; diff --git a/meeting-rooms/hwi-middle.cpp b/meeting-rooms/hwi-middle.cpp new file mode 100644 index 0000000000..556db6b71c --- /dev/null +++ b/meeting-rooms/hwi-middle.cpp @@ -0,0 +1,20 @@ +class Solution { +public: + bool canAttendMeetings(vector>& intervals) { + sort(intervals.begin(), intervals.end(), [](vector& a, vector& b) + { + return a[0] < b[0]; + }); + + int n = intervals.size(); + for (int i = 0; i < n - 1; ++i) + { + if (intervals[i][1] > intervals[i + 1][0]) + { + return false; + } + } + + return true; + } +}; From 60ff44cc7194f3ec743535222fc47ef063e2c31a Mon Sep 17 00:00:00 2001 From: Ju Hwijung Date: Wed, 3 Jun 2026 18:32:15 +0900 Subject: [PATCH 2/2] =?UTF-8?q?14=EC=A3=BC=EC=B0=A8=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=ED=92=80=EC=9D=B4=205=EA=B0=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hwi-middle.cpp | 51 ++++++ counting-bits/hwi-middle.cpp | 13 ++ house-robber-ii/hwi-middle.cpp | 25 +++ meeting-rooms-ii/hwi-middle.cpp | 39 +++++ word-search-ii/hwi-middle.cpp | 148 ++++++++++++++++++ 5 files changed, 276 insertions(+) create mode 100644 binary-tree-level-order-traversal/hwi-middle.cpp create mode 100644 counting-bits/hwi-middle.cpp create mode 100644 house-robber-ii/hwi-middle.cpp create mode 100644 meeting-rooms-ii/hwi-middle.cpp create mode 100644 word-search-ii/hwi-middle.cpp diff --git a/binary-tree-level-order-traversal/hwi-middle.cpp b/binary-tree-level-order-traversal/hwi-middle.cpp new file mode 100644 index 0000000000..2c2e0998dc --- /dev/null +++ b/binary-tree-level-order-traversal/hwi-middle.cpp @@ -0,0 +1,51 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + vector> levelOrder(TreeNode* root) { + vector> v; + if (root == nullptr) + { + return v; + } + + // BFS로 해결 + queue> q; + q.push({root, 0}); + while (!q.empty()) + { + TreeNode* cur; + int h; + tie(cur, h) = q.front(); + q.pop(); + + if (v.size() == h) + { + v.push_back(vector()); + } + + v[h].push_back(cur->val); + + if (cur->left != nullptr) + { + q.push({cur->left, h + 1}); + } + + if (cur->right != nullptr) + { + q.push({cur->right, h + 1}); + } + } + + return v; + } +}; diff --git a/counting-bits/hwi-middle.cpp b/counting-bits/hwi-middle.cpp new file mode 100644 index 0000000000..76081a4ae3 --- /dev/null +++ b/counting-bits/hwi-middle.cpp @@ -0,0 +1,13 @@ +class Solution { +public: + vector countBits(int n) { + // i & (i - 1)은 가장 오른쪽 비트 1을 지운다는 성질을 이용 + vector ans(n + 1); // ans[0]은 0으로 초기화 + for (int i = 1; i <= n; ++i) + { + ans[i] = ans[i & (i - 1)] + 1; + } + + return ans; + } +}; diff --git a/house-robber-ii/hwi-middle.cpp b/house-robber-ii/hwi-middle.cpp new file mode 100644 index 0000000000..6787db25aa --- /dev/null +++ b/house-robber-ii/hwi-middle.cpp @@ -0,0 +1,25 @@ +class Solution { +public: + int rob(vector& nums) { + if (nums.size() == 1) + { + return nums[0]; + } + + // 1번째 집과 n번째 집이 이웃하므로, [1, n)과 (1, n]에 대해 탐색 후 최댓값 반환 + return max(sol(span(nums).subspan(0, nums.size() - 1)), sol(span(nums).subspan(1))); + } + + int sol(span nums) { + int len = nums.size() + 1; + vector d(len); + d[0] = 0; + d[1] = nums[0]; + for(int i = 2; i < len; ++i) + { + d[i] = max(d[i - 1], d[i - 2] + nums[i - 1]); + } + + return d[len - 1]; + } +}; diff --git a/meeting-rooms-ii/hwi-middle.cpp b/meeting-rooms-ii/hwi-middle.cpp new file mode 100644 index 0000000000..a85b6251d2 --- /dev/null +++ b/meeting-rooms-ii/hwi-middle.cpp @@ -0,0 +1,39 @@ +class Solution { +public: + int minMeetingRooms(vector>& intervals) { + // 시작 시간이 빠른 순으로 정렬 + int n = intervals.size(); + sort(intervals.begin(), intervals.end(), [](vector& a, vector& b) + { + return a[0] < b[0]; + }); + + // 회의실이 부족할 때 마다 하나씩 추가 + // rooms에는 각 회의실을 마지막으로 이용한 회의의 종료 시간이 들어있음 + vector rooms; + rooms.push_back({intervals[0][1]}); + + for (int i = 1; i < n; ++i) + { + bool found = false; + for (auto& room : rooms) + { + // 빈 회의실을 찾은 경우 + if (room <= intervals[i][0]) + { + room = intervals[i][1]; + found = true; + break; + } + } + + // 빈 회의실을 찾지 못한 경우 + if (!found) + { + rooms.push_back(intervals[i][1]); + } + } + + return rooms.size(); + } +}; diff --git a/word-search-ii/hwi-middle.cpp b/word-search-ii/hwi-middle.cpp new file mode 100644 index 0000000000..8f3cbcf990 --- /dev/null +++ b/word-search-ii/hwi-middle.cpp @@ -0,0 +1,148 @@ +class Solution { +private: + // 트라이(Trie)를 활용 + struct Node + { + bool isWord = false; + Node* children[26]; + Node() : isWord(false) + { + fill(children, children + 26, nullptr); + } + + bool isEmpty() + { + for (int i = 0; i < 26; ++i) + { + if (children[i] != nullptr) + { + return false; + } + } + + return true; + } + }; + + // 각 노드는 배열로 관리 + static constexpr size_t POOL_SIZE = 300001; + Node pool[POOL_SIZE]; + int poolIdx = 0; + + Node* newNode() + { + pool[poolIdx] = Node(); + return &pool[poolIdx++]; + } + + Node* root; + vector ans; + int row; + int col; + +public: + vector findWords(vector>& board, vector& words) { + // 트라이 구성 시작 + poolIdx = 0; + ans.clear(); + root = newNode(); + for (auto& word : words) + { + Node* cur = root; + for (auto ch : word) + { + auto& child = cur->children[ch - 'a']; + if (child == nullptr) + { + child = newNode(); + } + + cur = child; + } + + cur->isWord = true; + } + + // 한 칸씩 탐색 시작 + row = board.size(); + col = board[0].size(); + for (int r = 0; r < row; ++r) + { + for (int c = 0; c < col; ++c) + { + string s = ""; + solve(board, root, s, r, c); + } + } + + return ans; + } + + void solve(vector>& board, Node*& node, string& s, int r, int c) + { + // 경로가 제거된 경우 + if (node == nullptr) + { + return; + } + + // 범위를 벗어난 경우 + if (r < 0 || r >= row || c < 0 || c >= col) + { + return; + } + + // 이미 방문한 경우 + char ch = board[r][c]; + if (ch == '?') + { + return; + } + + // 트라이에 이 문자가 없는 경우 (찾을 단어에 포함되지 않음) + if (node->children[ch - 'a'] == nullptr) + { + return; + } + + // 이 문자가 하나의 단어를 구성하는 경우 + if (node->children[ch - 'a']->isWord) + { + s.push_back(ch); + ans.push_back(s); + s.pop_back(); + node->children[ch - 'a']->isWord = false; // 중복 마킹 방지 + } + + board[r][c] = '?'; // 이미 방문한 곳으로 돌아오지 않도록 입력으로 들어오지 않는 문자로 치환 + + // 상하좌우 탐색 + static int dr[4] = { 1, 0, -1, 0 }; + static int dc[4] = { 0, 1, 0, -1 }; + + for (int dir = 0; dir < 4; ++dir) + { + int nr = r + dr[dir]; + int nc = c + dc[dir]; + s.push_back(ch); + solve(board, node->children[ch - 'a'], s, nr, nc); + s.pop_back(); + } + + board[r][c] = ch; // 원래 문자로 되돌리기 + + // 더 이상 탐색이 필요 없는 곳은 경로 자체를 제거 + // 일단 자식 먼저 판단 + Node*& child = node->children[ch - 'a']; + if (child != nullptr && !child->isWord && child->isEmpty()) + { + child = nullptr; + } + + // 자신도 지울 수 있으면 지움 + if (!node->isWord && node->isEmpty()) + { + node = nullptr; + } + } +};