Skip to content

[byol-han] WEEK 04 solutions #1348

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

Merged
merged 6 commits into from
Apr 26, 2025
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
26 changes: 26 additions & 0 deletions coin-change/byol-han.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @param {number[]} coins
* @param {number} amount
* @return {number}
*/
var coinChange = function (coins, amount) {
// dp[i]는 금액 i를 만들기 위한 최소 코인 수
const dp = new Array(amount + 1).fill(Infinity);

// 금액 0을 만들기 위해 필요한 코인 수는 0개
dp[0] = 0;

// 1부터 amount까지 반복
for (let i = 1; i <= amount; i++) {
// 각 금액마다 모든 코인 시도
for (let coin of coins) {
if (i - coin >= 0) {
// 코인을 하나 사용했을 때, 남은 금액의 최소 개수 + 1
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
}

// 만약 Infinity면 만들 수 없는 금액임
return dp[amount] === Infinity ? -1 : dp[amount];
};
22 changes: 22 additions & 0 deletions find-minimum-in-rotated-sorted-array/byol-han.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @param {number[]} nums
* @return {number}
*/
var findMin = function (nums) {
let left = 0;
let right = nums.length - 1;

while (left < right) {
let mid = Math.floor((left + right) / 2);

if (nums[mid] > nums[right]) {
// 최소값은 mid 오른쪽
left = mid + 1;
} else {
// 최소값은 mid 포함 왼쪽
right = mid;
}
}

return nums[left];
};
25 changes: 25 additions & 0 deletions maximum-depth-of-binary-tree/byol-han.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var maxDepth = function (root) {
// 트리가 비어있는 경우, 깊이는 0
if (!root) return 0;

// 왼쪽 서브트리의 최대 깊이를 재귀적으로 계산
const leftDepth = maxDepth(root.left);

// 오른쪽 서브트리의 최대 깊이를 재귀적으로 계산
const rightDepth = maxDepth(root.right);

// 왼쪽과 오른쪽 중 더 깊은 쪽을 선택하고, 현재 노드를 포함해 +1
return Math.max(leftDepth, rightDepth) + 1;
};
42 changes: 42 additions & 0 deletions merge-two-sorted-lists/byol-han.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} list1
* @param {ListNode} list2
* @return {ListNode}
*/
var mergeTwoLists = function (list1, list2) {
// 가짜(head 역할을 할) 임시 노드 생성
// 실제 결과 리스트는 dummy.next부터 시작됨
let dummy = new ListNode(-1);

// 현재 노드를 가리킬 포인터. 처음엔 dummy에서 시작
let current = dummy;

// 두 리스트 모두 null이 아닐 동안 반복 (비교 가능한 노드가 있을 때까지)
while (list1 !== null && list2 !== null) {
// list1의 현재 값이 더 작으면 list1 노드를 current.next에 붙임
if (list1.val < list2.val) {
current.next = list1; // current 뒤에 list1 노드 연결
list1 = list1.next; // list1 포인터를 다음 노드로 이동
} else {
current.next = list2; // current 뒤에 list2 노드 연결
list2 = list2.next; // list2 포인터를 다음 노드로 이동
}
current = current.next; // current 포인터도 다음 노드로 이동 (리스트를 계속 이어가기 위해)
}

// 위 반복문을 빠져나오면, 둘 중 하나는 null이 됨
// 나머지 하나는 아직 정렬된 상태이므로 그대로 뒤에 붙여줌
current.next = list1 !== null ? list1 : list2;

// dummy는 첫 번째 노드를 가리키는 용도였으니, 실제 결과 리스트는 dummy.next부터 시작
return dummy.next;
};
// 시간 복잡도: O(n + m) (n: list1의 길이, m: list2의 길이)
// 공간 복잡도: O(1) (추가적인 공간 사용 없음)
52 changes: 52 additions & 0 deletions word-search/byol-han.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* @param {character[][]} board
* @param {string} word
* @return {boolean}
*/
var exist = function (board, word) {
const rows = board.length;
const cols = board[0].length;

function backtrack(row, col, index) {
// 종료 조건: 모든 글자를 찾았으면 true
if (index === word.length) return true;

// 범위 밖이거나, 현재 칸 글자가 다르면 false
if (
row < 0 ||
row >= rows ||
col < 0 ||
col >= cols ||
board[row][col] !== word[index]
) {
return false;
}

// 방문 처리 (임시로 다른 문자로 바꿔줌)
const temp = board[row][col];
board[row][col] = "#";

// 상하좌우로 이동하면서 다음 글자 찾기
const found =
backtrack(row + 1, col, index + 1) || // 아래
backtrack(row - 1, col, index + 1) || // 위
backtrack(row, col + 1, index + 1) || // 오른쪽
backtrack(row, col - 1, index + 1); // 왼쪽

// 복구 (다시 원래 문자로 되돌리기)
board[row][col] = temp;

return found;
}

// board 전체 돌면서 시작점 찾기
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
if (backtrack(row, col, 0)) {
return true;
}
}
}

return false;
};