Skip to content

Commit 1a97d31

Browse files
authored
Merge pull request #1556 from sungjinwi/main
[sungjinwi] Week10 solution
2 parents 5e35d18 + 925e4b5 commit 1a97d31

File tree

5 files changed

+256
-0
lines changed

5 files changed

+256
-0
lines changed

course-schedule/sungjinwi.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
풀이 :
3+
BFS를 이용한 진입차수 기반 위상정렬
4+
5+
prerequisite에서 course로 방향 간선이 생기는 그래프 문제
6+
그래프는 이중벡터로 만들고 선수과목 관계에 따라 초기화 (graph[선수과목]에 상위과목들을 담는다)
7+
과목을 들으려면 필요한 선수과목 수 -> inDgree에 배열로 저장
8+
9+
선수과목이 필요없는 (inDgree에서 성분이 0인) 과목 먼저 큐에 넣는다
10+
과목을 수강하면 finished++로 수강완료 표시, 해당 과목을 선수과목으로 가지는 과목들에서 진입차수를 1씩 뺸다
11+
진입차수가 0이 되는 과목을 큐에 넣어서 반복
12+
13+
큐가 완전히 빌 떄까지 반복했을 떄 모든 과목을 이수 가능하면(finished == numCourses) true 아니면 false
14+
15+
수강과목 수 : V(Vertex), 선수과목 관계 수 : E(Edge)
16+
17+
TC : O (V + E)
18+
prerequisites(E)과 numCourses(V)만큼에 대해 각각 반복문
19+
20+
SC : O (V + E)
21+
기본적으로 V만큼의 빈 벡터를 가지고 있고 추가적으로 E만큼 성분이 push된다
22+
*/
23+
24+
#include <vector>
25+
#include <queue>
26+
27+
using namespace std;
28+
29+
class Solution {
30+
public:
31+
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
32+
vector<vector<int>> graph(numCourses);
33+
vector<int> inDgree(numCourses, 0);
34+
35+
for (auto& prerequisite : prerequisites) {
36+
int crs = prerequisite[0];
37+
int pre = prerequisite[1];
38+
graph[pre].push_back(crs);
39+
inDgree[crs]++;
40+
}
41+
42+
queue<int> q;
43+
int finished = 0;
44+
45+
for (int i = 0; i < numCourses; i++) {
46+
if (inDgree[i] == 0)
47+
q.push(i);
48+
}
49+
50+
while (!q.empty()) {
51+
int cur = q.front();
52+
q.pop();
53+
54+
for (auto& next : graph[cur]) {
55+
if (--inDgree[next] == 0)
56+
q.push(next);
57+
}
58+
finished++;
59+
}
60+
61+
return finished == numCourses;
62+
}
63+
};

invert-binary-tree/sungjinwi.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
풀이 :
3+
left와 right을 스왑하는 과정을 dfs를 이용해서 끝까지 반복한다
4+
5+
트리의 깊이 : N
6+
7+
TC : O(2^N)
8+
깊이마다 2번씩 재귀함수 호출
9+
10+
SC : O(2^N)
11+
깊이마다 2번씩 재귀함수 호출로 인한 스택 쌓임
12+
*/
13+
14+
/**
15+
* Definition for a binary tree node.
16+
* struct TreeNode {
17+
* int val;
18+
* TreeNode *left;
19+
* TreeNode *right;
20+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
21+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
22+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
23+
* };
24+
*/
25+
class Solution {
26+
public:
27+
TreeNode* invertTree(TreeNode* root) {
28+
if (!root)
29+
return nullptr;
30+
31+
TreeNode* tmp = root->left;
32+
33+
root->left = root->right;
34+
root->right = tmp;
35+
36+
invertTree(root->left);
37+
invertTree(root->right);
38+
39+
return root;
40+
}
41+
};
42+
43+
struct TreeNode {
44+
int val;
45+
TreeNode *left;
46+
TreeNode *right;
47+
TreeNode() : val(0), left(nullptr), right(nullptr) {}
48+
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
49+
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
50+
};

jump-game/sungjinwi.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
풀이 :
3+
마지막 인덱스를 시작점으로 하는 변수 lastReachable 선언
4+
마지막 인덱스에 도달할 수 있는 가장 작은 인덱스를 저장
5+
위에서 내려오면서 lastReachable 높이에 점프해서 닿을 수 있는 가장 작은 높이를 새로운 lastReachable로 업데이트
6+
반복문이 끝나고 lastReachable == 0을 리턴한다
7+
8+
nums의 길이 : N
9+
10+
TC : O(N)
11+
for문 반복 1회
12+
13+
SC : O(1)
14+
변수 lastReachable 외에 추가적인 메모리 할당 없음
15+
*/
16+
17+
#include <vector>
18+
using namespace std;
19+
20+
class Solution {
21+
public:
22+
bool canJump(vector<int>& nums) {
23+
int lastReachable = nums.size() - 1;
24+
25+
for (int i = nums.size() - 2; i >= 0; i--) {
26+
if (i + nums[i] >= lastReachable)
27+
lastReachable = i;
28+
}
29+
30+
return lastReachable == 0;
31+
}
32+
};

merge-k-sorted-lists/sungjinwi.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
풀이 :
3+
최소힙을 사용해서 풀이한다
4+
리스트의 각 맨앞 노드를 최소힙에 넣고 최소 값을 가진 노드를 dummy에 붙여나간 뒤 next를 다시 최소힙에 넣는 것을 반복
5+
6+
노드의 개수 : N, list의 개수 K
7+
8+
TC : O (N log K)
9+
K개의 크기를 가지는 최소 힙에 넣고 제거하는 시간 -> logK * 모든 노드에 대한 순회 N
10+
11+
SC : O (K)
12+
최소힙 크기는 K에 비례
13+
*/
14+
15+
#include <vector>
16+
#include <queue>
17+
18+
using namespace std;
19+
20+
/**
21+
* Definition for singly-linked list.
22+
* struct ListNode {
23+
* int val;
24+
* ListNode *next;
25+
* ListNode() : val(0), next(nullptr) {}
26+
* ListNode(int x) : val(x), next(nullptr) {}
27+
* ListNode(int x, ListNode *next) : val(x), next(next) {}
28+
* };
29+
*/
30+
31+
struct cmp {
32+
bool operator()(const ListNode* a, const ListNode* b) {
33+
return a->val > b->val;
34+
}
35+
};
36+
37+
class Solution {
38+
public:
39+
ListNode* mergeKLists(vector<ListNode*>& lists) {
40+
priority_queue<ListNode*, vector<ListNode*>, cmp> pq;
41+
42+
for (auto list : lists) {
43+
if (list)
44+
pq.push(list);
45+
}
46+
47+
ListNode dummy, *tail = &dummy;
48+
49+
while (!pq.empty()) {
50+
ListNode* minNode = pq.top(); pq.pop();
51+
52+
if (minNode->next)
53+
pq.push(minNode->next);
54+
55+
tail->next = minNode;
56+
tail = minNode;
57+
}
58+
return dummy.next;
59+
}
60+
};
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
풀이 :
3+
mid를 기준으로 왼쪽이 정렬된 경우, 오른쪽이 정렬된 경우를 나누고
4+
정렬된 숫자 범위에 target값이 존재하느냐에 따라 범위를 이분 탐색으로 좁혀나간다
5+
6+
- 이분탐색 시 종료조건 및 비교조건에서 등호를 포함시킬지 여부 고려 필요
7+
while (left <= right) -> 탐색 범위에 양 끝 인덱스 포함
8+
-> left = mid + 1 또는 right = mid - 1 로 새로운 범위 업데이트
9+
10+
while (left < right) -> 탐색 범위에 오른쪽 끝 인덱스는 제외
11+
-> left = mid + 1 또는 right = mid 로 새로운 범위 업데이트
12+
13+
nums 개수 N
14+
15+
TC : O(logN)
16+
이분 탐색으로 찾아서 log2N의 복잡도를 갖는다
17+
18+
SC : O(1)
19+
*/
20+
21+
#include <vector>
22+
using namespace std;
23+
24+
class Solution {
25+
public:
26+
int search(vector<int>& nums, int target) {
27+
int left = 0, right = nums.size() - 1;
28+
29+
while (left <= right)
30+
{
31+
int mid = left + (right - left) / 2;
32+
33+
if (nums[mid] == target)
34+
return mid;
35+
36+
if (nums[left] <= nums[mid]) {
37+
if (nums[left] <= target && target < nums[mid])
38+
right = mid -1;
39+
else
40+
left = mid + 1;
41+
}
42+
else {
43+
if (nums[mid] < target && target <= nums[right])
44+
left = mid + 1;
45+
else
46+
right = mid - 1;
47+
}
48+
}
49+
return -1;
50+
}
51+
};

0 commit comments

Comments
 (0)