Skip to content

Commit e562f5a

Browse files
authored
Merge pull request #1375 from sungjinwi/main
[sungjinwi] Week 04 Solution
2 parents 32bf681 + a4d8f65 commit e562f5a

File tree

5 files changed

+215
-0
lines changed

5 files changed

+215
-0
lines changed

coin-change/sungjinwi.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
풀이 :
3+
bottom-up dp 활용, 낮은 수부터 amount까지 차례로 해당 금액을 만들 수 있는 최소 동전 개수를 업데이트.
4+
amount가 0이면 동전 개수 0이므로 dp[0] = 0으로 초기화
5+
그 외의 초기값은 amount + 1로 설정
6+
(1짜리 동전으로 채우면 dp[amount] 최댓값 == amount이므로 amount + 1 그대로이면 채울 수 없는 케이스)
7+
8+
coin 종류 : C, amount 크기 : A
9+
10+
TC : O(A * C)
11+
amount의 크기 * coin 종류만큼 반복문
12+
13+
SC : O(A)
14+
dp배열의 크기는 amount 크기에 비례
15+
*/
16+
17+
class Solution {
18+
public:
19+
int coinChange(vector<int>& coins, int amount) {
20+
vector<int> dp(amount + 1, amount + 1);
21+
22+
dp[0] = 0;
23+
for (int i = 0; i <= amount; i++)
24+
{
25+
for (auto coin : coins)
26+
{
27+
if (i - coin >= 0)
28+
dp[i] = min(dp[i - coin] + 1, dp[i]);
29+
}
30+
}
31+
if (dp[amount] == amount + 1)
32+
return -1;
33+
else
34+
return dp[amount];
35+
}
36+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
풀이 :
3+
O(logN)의 시간복잡도를 달성하기 위해 이진탐색
4+
5+
case 1: nums[mid] < nums[right]
6+
mid부터 right까지는 정렬된 상태
7+
따라서 min은 인덱스 left부터 mid에 존재할 가능성이 있으므로 right = mid로 업데이트
8+
9+
case 2: else
10+
mid와 right 사이에 min이 오도록 rotate 되어있는 상태
11+
left부터 mid까지는 min이 존재할 수 없으므로 left = mid + 1로 업데이트
12+
13+
이 두 조건문에 따라 최소값이 포함된 쪽만 남기면 결국 left == right이 되고 이 인덱스의 수를 return
14+
15+
nums의 길이: N
16+
17+
TC : O(logN)
18+
반으로 나눠서 탐색하는 이진탐색이므로 log2(N)의 시간복잡도를 가진다
19+
20+
SC : O(1)
21+
*/
22+
23+
class Solution {
24+
public:
25+
int findMin(vector<int>& nums) {
26+
int left = 0;
27+
int right = nums.size() - 1;
28+
while (left < right)
29+
{
30+
int mid = (left + right) / 2;
31+
if (nums[left] < nums[right])
32+
return nums[left];
33+
else
34+
{
35+
if (nums[mid] < nums[right])
36+
right = mid;
37+
else
38+
left = mid + 1;
39+
}
40+
}
41+
return nums[left];
42+
}
43+
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
풀이 :
3+
dfs를 이용해 모든 노드를 탐색하며 가장 하위노드에서 바텀업 방식으로 depth를 1씩 쌓아나가서
4+
최상위 노드의 depth를 구한다
5+
6+
노드의 개수 : N
7+
8+
TC : O(N)
9+
전체 노드를 순회하므로 O(N)
10+
11+
SC : O(N)
12+
재귀호출 스택이 노드 개수만큼 쌓이므로 O(N)
13+
*/
14+
15+
/**
16+
* Definition for a binary tree node.
17+
* struct TreeNode {
18+
* int val;
19+
* TreeNode *left;
20+
* TreeNode *right;
21+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
22+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
23+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
24+
* };
25+
*/
26+
class Solution {
27+
public:
28+
int maxDepth(TreeNode* root) {
29+
if (!root)
30+
return 0;
31+
return max(maxDepth(root->left) + 1, maxDepth(root->right) + 1);
32+
}
33+
};

merge-two-sorted-lists/sungjinwi.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
풀이 :
3+
dummy를 맨 앞에 세우고 list1과 list2의 맨 앞 성분 value를 비교하며 dummy 뒤에 노드를 이어줌
4+
이어준 list는 next로 전진시키면서 계속 반복문
5+
둘 중 하나가 null이 되면 남은 리스트 전체를 맨 뒤에 이어줌
6+
7+
리스트 길이 : M, N
8+
9+
TC : O(M + N)
10+
번갈아서 나올 경우 두 리스트 전체의 길이에 비례
11+
12+
SC : O(1)
13+
기존 노드를 활용하므로 추가적인 메모리는 dummy와 tmp만 사용한다
14+
*/
15+
16+
/**
17+
* Definition for singly-linked list.
18+
* struct ListNode {
19+
* int val;
20+
* ListNode *next;
21+
* ListNode() : val(0), next(nullptr) {}
22+
* ListNode(int x) : val(x), next(nullptr) {}
23+
* ListNode(int x, ListNode *next) : val(x), next(next) {}
24+
* };
25+
*/
26+
class Solution {
27+
public:
28+
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
29+
ListNode dummy;
30+
ListNode *tmp;
31+
32+
tmp = &dummy;
33+
while (list1 && list2)
34+
{
35+
if (list1->val <= list2->val)
36+
{
37+
tmp->next = list1;
38+
list1 = list1->next;
39+
}
40+
else
41+
{
42+
tmp->next = list2;
43+
list2 = list2->next;
44+
}
45+
tmp = tmp->next;
46+
}
47+
if (list1)
48+
tmp->next = list1;
49+
else
50+
tmp->next = list2;
51+
return dummy.next;
52+
}
53+
};

word-search/sungjinwi.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
풀이:
3+
dfs를 이용해 board의 각 칸에서 출발해서 4방향으로 board를 탐색
4+
word[index]와 일치하는 글자의 칸이 있으면 index + 1 시키면서 단어 끝 index까지 탐색
5+
6+
- 탐색 중인 칸을 다른 char(#)로 바꿔서 이미 경로상에 있는 칸이라고 표시해주고 탐색 끝난 후 다시 되돌린다
7+
- board를 변경할 수 없다면 unordered_set(해시테이블)로 중복 방문을 제거하거나 bool[row][col] 이중 배열로 방문된 칸 표시
8+
9+
board 크기 : M * N, word 길이 W
10+
11+
TC : O(M * N * 4^W)
12+
board 전체 순회하고 각 칸 마다 4방향으로 word길이 만큼 재귀호출
13+
14+
SC : O(W)
15+
재귀호출 스택이 word의 길이와 비례
16+
*/
17+
18+
class Solution {
19+
public:
20+
bool exist(vector<vector<char>>& board, string word) {
21+
for (int i = 0; i < board.size(); ++i) {
22+
for (int j = 0; j < board[0].size(); ++j) {
23+
if (dfs(board, word, i, j, 0)) {
24+
return true;
25+
}
26+
}
27+
}
28+
return false;
29+
}
30+
private:
31+
bool dfs(vector<vector<char>>& board, const string& word, int i, int j, int index) {
32+
if (index == word.size())
33+
return true;
34+
if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size())
35+
return false;
36+
if (board[i][j] != word[index])
37+
return false;
38+
39+
char tmp = board[i][j];
40+
41+
board[i][j] = '#';
42+
bool found = dfs(board, word, i + 1, j, index + 1) ||
43+
dfs(board, word, i - 1, j, index + 1) ||
44+
dfs(board, word, i, j + 1, index + 1) ||
45+
dfs(board, word, i, j - 1, index + 1);
46+
board[i][j] = tmp;
47+
48+
return found;
49+
}
50+
};

0 commit comments

Comments
 (0)