Skip to content

Commit c8bf354

Browse files
authored
Merge pull request #1578 from sungjinwi/main
[sungjinwi] Week 11 solution
2 parents d7cf0b1 + 922d20b commit c8bf354

File tree

5 files changed

+234
-0
lines changed

5 files changed

+234
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
풀이 :
3+
result를 int의 최솟값으로 초기화하고 시작
4+
5+
두가지 기능을 하는 함수 하나를 생성
6+
1. left, root->val, right의 합(하나의 path/\를 이룸)을 통해 maxSum을 업데이트
7+
2. max (left 노드 합, right 노드 합)과 root를 더해서 return
8+
-> left, right 둘 중 하나만 포함해야 상위 tree에서 path의 일부로 사용가능
9+
/\
10+
/ \
11+
/ /
12+
\
13+
이 때, 음수 노드의 합은 max(0, value)를 통해 버리고 left + right + root->val을 통해 추가적인 계산 없이 maxSum 업데이트
14+
15+
노드 개수 : N
16+
17+
TC : O(N)
18+
모든 노드 순회
19+
20+
SC : O(N)
21+
재귀 호출 스택도 노드 개수에 비례
22+
*/
23+
24+
25+
#include <limits.h>
26+
#include <algorithm>
27+
28+
using namespace std;
29+
30+
class Solution {
31+
public:
32+
int maxPathSum(TreeNode* root) {
33+
int result = INT_MIN;
34+
35+
dfs(root, result);
36+
return result;
37+
}
38+
39+
int dfs(TreeNode* root, int& maxSum) {
40+
if (!root)
41+
return 0;
42+
43+
int left = max(0, dfs(root->left, maxSum));
44+
int right = max(0, dfs(root->right, maxSum));
45+
46+
maxSum = max(maxSum, left + right + root->val);
47+
48+
return root->val + max(left, right);
49+
}
50+
};
51+
52+
struct TreeNode {
53+
int val;
54+
TreeNode *left;
55+
TreeNode *right;
56+
TreeNode() : val(0), left(nullptr), right(nullptr) {}
57+
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
58+
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
59+
};

graph-valid-tree/sungjinwi.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
풀이 :
3+
graph가 tree가 되려면 모든 노드가 연결되어 있어야하고 순환이 없어야한다
4+
간선이 노드 개수 n - 1보다 작으면 모든 노드 연결 불가능, 크면 무조건 순환이 생긴다
5+
간선이 n - 1과 동일할 때 순환이 없으면 valid tree라고 판단 가능
6+
7+
Union-find 사용
8+
- 시작할 때 각 노드는 자기 자신을 parent(root)로 가진다
9+
- 노드가 서로 연결되있으면 한 union으로 합친 뒤 하나의 parent로 업데이트한다
10+
- 이를 통해 한 parent를 가지는 한 그룹으로 묶이게 된다
11+
12+
find 함수는 한 그룹 전체의 parent를 재귀적으로 한 노드로 업데이트한다 (트리 깊이가 깊어져도 한번에 parent를 찾을 수 있게끔 경로최적화)
13+
14+
두 노드의 find()결과 값이 같으면 이미 한 그룹에 속하는 것이므로 이 두 노드에 간선을 잇는 것은 순환이 생기는 것이다
15+
이를 통해 순환 있는지 판단
16+
17+
노드 개수 : V, 간선 개수 : E
18+
E = V - 1일 때만 유의미한 연산하므로 E ≈ V
19+
20+
TC : O(V)
21+
반복문 2회, find 함수의 재귀는 이론적으로 상수에 수렴한다고 한다
22+
23+
SC : O(V)
24+
parent 배열
25+
*/
26+
27+
#include <vector>
28+
#include <unordered_map>
29+
30+
using namespace std;
31+
32+
class Solution {
33+
public:
34+
/**
35+
* @param n: An integer
36+
* @param edges: a list of undirected edges
37+
* @return: true if it's a valid tree, or false
38+
*/
39+
vector<int> parent;
40+
bool validTree(int n, vector<vector<int>> &edges) {
41+
if (edges.size() != n - 1)
42+
return false;
43+
44+
parent.resize(n);
45+
for (int i = 0; i < n; i++)
46+
parent[i] = i;
47+
48+
for (auto& edge : edges) {
49+
int a = edge[0], b = edge[1];
50+
int rootA = find(a), rootB = find(b);
51+
if (rootA == rootB)
52+
return false;
53+
parent[rootA] = rootB;
54+
}
55+
}
56+
57+
int find(int x) {
58+
if (parent[x] != x)
59+
parent[x] = find(parent[x]);
60+
return parent[x];
61+
}
62+
};

merge-intervals/sungjinwi.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
풀이 :
3+
시작시간으로 interval을 정렬한 뒤에 첫번째 interval을 ans에 넣는다(.back() 메서드의 에러 방지)
4+
ans 배열의 마지막 interval과 시간이 겹치면 interval을 통합시키고
5+
겹치지 않으면 ans에 현재 interval을 넣고 반복
6+
7+
interval 개수 : N
8+
9+
TC : O (N logN)
10+
sort로 정렬
11+
12+
SC : O (1)
13+
ans외에 추가적인 메모리 할당은 상수
14+
*/
15+
16+
#include <vector>
17+
#include <algorithm>
18+
using namespace std;
19+
20+
class Solution {
21+
public:
22+
vector<vector<int>> merge(vector<vector<int>>& intervals) {
23+
vector<vector<int>> ans;
24+
25+
sort(intervals.begin(), intervals.end());
26+
ans.push_back(intervals[0]);
27+
28+
for (int i = 1; i < intervals.size(); i++) {
29+
vector<int>& lastInterval = ans.back();
30+
31+
if (intervals[i][0] <= lastInterval[1])
32+
lastInterval[1] = max(lastInterval[1], intervals[i][1]);
33+
else
34+
ans.push_back(intervals[i]);
35+
}
36+
return ans;
37+
}
38+
};

missing-number/sungjinwi.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
풀이 :
3+
수식을 이용해 숫자가 빠지지 않았을경우 총합을 구하고 nums를 순회하면서 숫자들을 빼면 남은 숫자가 missing No.
4+
5+
nums의 길이 : N
6+
7+
TC : O(N)
8+
9+
SC : O(1)
10+
*/
11+
12+
#include <vector>
13+
using namespace std;
14+
15+
class Solution {
16+
public:
17+
int missingNumber(vector<int>& nums) {
18+
int n = nums.size();
19+
int sum = n * (n + 1) / 2;
20+
21+
for (auto& num : nums)
22+
sum -= num;
23+
return sum;
24+
}
25+
};

reorder-list/sungjinwi.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
풀이 :
3+
투포인터 기법을 이용해 중간 노드를 구해 리스트를 반으로 나누고 뒤의 그룹은 순서를 뒤집는다
4+
번갈아가면서 다시 붙여준다
5+
6+
노드 총 개수 : N
7+
8+
TC : O(N)
9+
10+
SC : O(1)
11+
*/
12+
13+
class Solution {
14+
public:
15+
void reorderList(ListNode* head) {
16+
ListNode *slow = head, *fast = head;
17+
18+
while (fast && fast->next) {
19+
slow = slow->next;
20+
fast = fast->next->next;
21+
}
22+
23+
ListNode *prev = nullptr, *curr = slow->next;
24+
slow->next = nullptr;
25+
26+
while (curr) {
27+
ListNode *tmp = curr->next;
28+
curr->next = prev;
29+
prev = curr;
30+
curr = tmp;
31+
}
32+
33+
ListNode *first = head, *second = prev;
34+
while (second) {
35+
ListNode *tmp1 = first->next, *tmp2 = second->next;
36+
first->next = second;
37+
second->next = tmp1;
38+
first = tmp1;
39+
second = tmp2;
40+
}
41+
}
42+
};
43+
44+
struct ListNode {
45+
int val;
46+
ListNode *next;
47+
ListNode() : val(0), next(nullptr) {}
48+
ListNode(int x) : val(x), next(nullptr) {}
49+
ListNode(int x, ListNode *next) : val(x), next(next) {}
50+
};

0 commit comments

Comments
 (0)