-
-
Notifications
You must be signed in to change notification settings - Fork 334
[hwi-middle] WEEK 14 solutions #2625
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<vector<int>> levelOrder(TreeNode* root) { | ||
| vector<vector<int>> v; | ||
| if (root == nullptr) | ||
| { | ||
| return v; | ||
| } | ||
|
|
||
| // BFS로 해결 | ||
| queue<pair<TreeNode*, int>> 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<int>()); | ||
| } | ||
|
|
||
| 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; | ||
| } | ||
| }; |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: DP를 활용하여 i & (i - 1) 연산으로 이전 값에 1을 더하는 방식으로 계산, 모든 수에 대해 한 번씩 계산하므로 시간 복잡도는 O(n). 배열 크기만큼 저장하므로 공간도 O(n). 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| class Solution { | ||
| public: | ||
| vector<int> countBits(int n) { | ||
| // i & (i - 1)은 가장 오른쪽 비트 1을 지운다는 성질을 이용 | ||
| vector<int> ans(n + 1); // ans[0]은 0으로 초기화 | ||
| for (int i = 1; i <= n; ++i) | ||
| { | ||
| ans[i] = ans[i & (i - 1)] + 1; | ||
| } | ||
|
|
||
| return ans; | ||
| } | ||
| }; |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 힙을 이용한 균형 유지로 삽입과 조회 모두 O(log n). 공간은 저장된 숫자 개수에 비례하여 O(n). 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<int> maxHeap; | ||
| priority_queue<int, vector<int>, greater<int>> minHeap; | ||
| }; | ||
|
|
||
| /** | ||
| * Your MedianFinder object will be instantiated and called as such: | ||
| * MedianFinder* obj = new MedianFinder(); | ||
| * obj->addNum(num); | ||
| * double param_2 = obj->findMedian(); | ||
| */ |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 두 개의 선형 문제로 나누어 DP 계산, 각각 O(n). 전체 시간은 O(n). 공간도 DP 배열 크기만큼 사용. 개선 제안: 현재 구현이 적절해 보입니다.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| class Solution { | ||
| public: | ||
| int rob(vector<int>& 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<int> nums) { | ||
| int len = nums.size() + 1; | ||
| vector<int> 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]; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| class Solution { | ||
| public: | ||
| vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) { | ||
| int n = intervals.size(); | ||
| vector<vector<int>> 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; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| class Solution { | ||
| public: | ||
| int minMeetingRooms(vector<vector<int>>& intervals) { | ||
| // 시작 시간이 빠른 순으로 정렬 | ||
| int n = intervals.size(); | ||
| sort(intervals.begin(), intervals.end(), [](vector<int>& a, vector<int>& b) | ||
| { | ||
| return a[0] < b[0]; | ||
| }); | ||
|
|
||
| // 회의실이 부족할 때 마다 하나씩 추가 | ||
| // rooms에는 각 회의실을 마지막으로 이용한 회의의 종료 시간이 들어있음 | ||
| vector<int> 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(); | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| class Solution { | ||
| public: | ||
| bool canAttendMeetings(vector<vector<int>>& intervals) { | ||
| sort(intervals.begin(), intervals.end(), [](vector<int>& a, vector<int>& 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; | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
피드백: 큐를 이용한 BFS로 모든 노드를 한 번씩 방문하므로 시간 복잡도는 O(n). 큐와 결과 벡터에 노드 수만큼 저장하므로 공간 복잡도도 O(n).
개선 제안: 현재 구현이 적절해 보입니다.