Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions binary-tree-maximum-path-sum/hwi-middle.cpp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

  • 패턴: Divide and Conquer, Binary Search
  • 설명: 이 코드는 트리 구조를 재귀적으로 탐색하며 최댓값을 찾는 분할 정복 방식을 사용합니다. 또한, 트리의 특정 조건을 만족하는 값을 찾기 위해 이진 탐색과 유사한 재귀적 접근을 활용합니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(h)

피드백: 트리의 모든 노드를 한 번씩 방문하는 DFS로 구현되어 있으며, 호출 스택은 트리의 높이만큼 사용됩니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* 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 maxPathSum(TreeNode* root) {
int ans = -1000;
impl(root, ans);
return ans;
}

private:
int impl(TreeNode* root, int& ans)
{
if (root == nullptr)
{
return 0;
}

// 왼쪽과 오른쪽 자식을 재귀적으로 순회
int l = impl(root->left, ans);
int r = impl(root->right, ans);
int cur = root->val;

// 최댓값 업데이트
ans = max(ans, max(0, l) + max(0, r) + cur);

// 부모에게 전달할 값
// -> 재방문이 허용되지 않으므로 최댓값과는 다름
return max(0, max(l, r) + cur);
}
};
47 changes: 47 additions & 0 deletions graph-valid-tree/hwi-middle.cpp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

  • 패턴: BFS
  • 설명: 이 코드는 그래프의 유효성을 검사하기 위해 BFS를 사용하여 노드들을 탐색하며, 연결성과 사이클 여부를 판단합니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n + m)
Space O(n)

피드백: 인접 리스트와 BFS를 활용하여 모든 노드를 방문하며, 방문 여부와 부모 노드 체크로 사이클을 검증합니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
class Solution {
public:
bool validTree(int n, vector<vector<int>>& edges) {
vector<vector<int>> adj(n + 1);
vector<bool> vis(n + 1);

for (vector<int>& edge : edges)
{
adj[edge[0]].push_back(edge[1]);
adj[edge[1]].push_back(edge[0]);
}

// BFS 수행
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오.. BFS로 푸셨군요(저는 DFS로 풀었기에 대비되는 점!)

그래프 탐색 문제니 무엇으로 풀어도 되겠으나 덕분에 한 번 더 인지하고 갑니다!

int visited = 1;
queue<pair<int, int>> q;
q.push({0, -1});
while (!q.empty())
{
int cur;
int parent;
tie(cur, parent) = q.front();
q.pop();

for (int n : adj[cur])
{
// 자기가 왔던 노드면 넘어감
if (n == parent)
{
continue;
}

// 이미 방문한 노드면 유효하지 않음
if (vis[n])
{
return false;
}

vis[n] = true;
visited++;
q.push({n, cur});
}
}

// BFS를 통해 전체 노드를 방문할 수 있었어야 함
return visited == n;
}
};
39 changes: 39 additions & 0 deletions merge-intervals/hwi-middle.cpp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

  • 패턴: Sorting, Interval Merging
  • 설명: 이 코드는 구간들을 시작점 기준으로 정렬한 후, 연속된 구간들을 병합하는 방식으로 동작합니다. 정렬 후 순차적으로 구간을 비교하며 병합하는 과정이 핵심입니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n log n)
Space O(n)

피드백: 정렬 후 선형 순회로 병합하는 방식으로, 정렬이 가장 큰 시간 복잡도를 차지합니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
// start 순으로 정렬
sort(intervals.begin(), intervals.end(),
[](const vector<int>& a, const vector<int>& b) {
return a[0] < b[0];
});

vector<vector<int>> res;
res.reserve(intervals.size());

int start = intervals[0][0];
int end = intervals[0][1];

for (int i = 1; i < intervals.size(); ++i)
{
// 현재 구간의 end보다 start가 크다면 틈이 벌어진 것
if (end < intervals[i][0])
{
vector<int> v = { start, end };
res.push_back(v);
start = intervals[i][0];
end = intervals[i][1];
}
// 그렇지 아니면 합칠 수 있음
else
{
start = min(start, intervals[i][0]);
end = max(end, intervals[i][1]);
}
}

vector<int> v = { start, end };
res.push_back(v);

return res;
}
};
15 changes: 15 additions & 0 deletions missing-number/hwi-middle.cpp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

  • 패턴: Math
  • 설명: 이 코드는 수학적 공식을 이용하여 빠진 숫자를 찾는 방법으로, 특정 알고리즘 패턴에 속하지 않으며 수학적 계산을 활용한 해결법입니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(1)

피드백: 수열의 합 공식과 배열 요소의 합을 차감하는 방식으로, 시간은 선형, 공간은 상수입니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Solution {
public:
int missingNumber(vector<int>& nums) {
// 1부터 n까지 합을 구하고, 배열 요소들의 합을 빼서 빠진 수를 찾음
int n = nums.size();
int sum = (n * (n + 1)) / 2;
int acc = 0;
for (int num : nums)
{
acc += num;
}

return sum - acc;
}
};
53 changes: 53 additions & 0 deletions reorder-list/hwi-middle.cpp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏷️ 알고리즘 패턴 분석

  • 패턴: Fast & Slow Pointers, Reverse Linked List
  • 설명: 이 코드는 빠른-느린 포인터를 이용해 리스트를 반으로 나누고, 후반 리스트를 뒤집은 후 두 리스트를 병합하는 과정을 포함하여, 두 포인터 패턴과 리스트 뒤집기 패턴이 사용됩니다.

📊 시간/공간 복잡도 분석

복잡도
Time O(n)
Space O(1)

피드백: 포인터를 활용한 단계별 리스트 조작으로, 각 단계는 선형 시간 내 수행됩니다.

개선 제안: 현재 구현이 적절해 보입니다.

💡 풀이에 시간/공간 복잡도를 주석으로 남겨보세요!

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/

// Editorial 코드
class Solution {
public:
void reorderList(ListNode* head) {
if (head == nullptr)
{
return;
}

ListNode* slow = head;
ListNode* fast = head;
while (fast != nullptr && fast->next != nullptr)
{
slow = slow->next;
fast = fast->next->next;
}

ListNode* prev = nullptr;
ListNode* curr = slow;
ListNode* tmp;
while (curr != nullptr)
{
tmp = curr->next;
curr->next = prev;
prev = curr;
curr = tmp;
}


ListNode* first = head;
ListNode* second = prev;
while (second->next != nullptr)
{
tmp = first->next;
first->next = second;
first = tmp;
tmp = second->next;
second->next = first;
second = tmp;
}
}
};
Loading