Skip to content

[JANGSEYEONG] WEEK 04 solutions #1356

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 5 commits into from
Apr 28, 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
22 changes: 22 additions & 0 deletions coin-change/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @param {number[]} coins
* @param {number} amount
* @return {number}
*/
var coinChange = function (coins, amount) {
// f(n) = n을 만드는데 필요한 동전의 최소 개수
// f(n) = min(f(n), f(n-coin) + 1)

// dp 배열 초기화: 모든 금액을 만드는데 필요한 동전 개수를 불가능한 값(amount+1)으로 설정
const dp = new Array(amount + 1).fill(amount + 1);
dp[0] = 0; // 0원은 0개의 동전으로 만들 수 있음
coins.forEach((coin) => {
for (let i = coin; i < dp.length; i++) {
// dp[i]: 기존에 계산된 i원을 만드는 최소 동전 개수
// dp[i-coin] + 1: (i-coin)원에 현재 동전 하나를 추가하여 i원을 만드는 경우
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
});
// 목표 금액을 만들 수 없으면 -1 반환, 가능하면 최소 동전 개수 반환
return dp[amount] < amount + 1 ? dp[amount] : -1;
};
33 changes: 33 additions & 0 deletions find-minimum-in-rotated-sorted-array/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*var findMin = function (nums) {
while (nums.length !== 1) {
if (nums[0] > nums[nums.length - 1]) {
// 앞에서 하나씩 자르기
nums = nums.slice(1, nums.length);
} else {
return nums[0];
}
}
return nums[0];
};*/
/**
* 위의 풀이처럼 풀면 최악의 경우 O(n)이 되어버림. 양 끝을 포인터로 가리키면서 이진탐색
*/
/**
* @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]) {
left = mid + 1;
} else {
right = mid;
}
}

return nums[left];
};
31 changes: 31 additions & 0 deletions maximum-depth-of-binary-tree/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* 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) {
if (!root) return 0; // 노드가 없으면 깊이는 0

// 현재 노드가 존재하므로 기본 깊이는 1
// 자식이 아예 없는 경우를 대비해 초기값 설정
let left = 1;
let right = 1;

// 왼쪽 서브트리가 있으면 재귀적으로 깊이 계산 후 현재 레벨(+1) 추가
if (root.left) {
left = maxDepth(root.left) + 1;
}
// 오른쪽 서브트리가 있으면 재귀적으로 깊이 계산 후 현재 레벨(+1) 추가
if (root.right) {
right = maxDepth(root.right) + 1;
}
// 왼쪽과 오른쪽 서브트리 중 더 깊은 값을 반환
return Math.max(left, right);
};
34 changes: 34 additions & 0 deletions merge-two-sorted-lists/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* 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) {
const answer = new ListNode();
let temp = answer; // answer은 head를 가지고 있어야함

// list1, list2 중 하나라도 끝까지 도달할 때 까지 루프 돌리기
while (list1 && list2) {
// 더 작은수를 가진 리스트를 연결
if (list1.val < list2.val) {
temp.next = list1;
list1 = list1.next;
} else {
temp.next = list2;
list2 = list2.next;
}
temp = temp.next;
}

// list1, list2 중 어떤게 끝까지 갔는지 몰라서 둘 다 체크
// 남은건 그냥 뒤에 가져다가 붙이기
temp.next = list1 || list2;
return answer.next;
};
50 changes: 50 additions & 0 deletions word-search/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* @param {character[][]} board
* @param {string} word
* @return {boolean}
*/
// DFS 사용 이유: 한 경로를 끝까지 탐색해야 하고, 경로별로 독립적인 방문 상태가 필요하기 때문
// BFS 불가 이유: 여러 경로를 동시에 탐색하면서 방문 상태가 섞여 올바른 경로를 놓칠 수 있음
var exist = function (board, word) {
for (let y = 0; y < board.length; y++) {
for (let x = 0; x < board[0].length; x++) {
// 시작이 되는 단어를 마주치면 dfs 돌려보기
if (board[y][x] === word[0] && dfs(board, y, x, word, 0)) {
return true;
}
}
}
return false;
};

function dfs(board, y, x, word, index) {
// 성공 조건: 모든 문자를 찾았을 때
if (index === word.length) return true;

// 실패 조건: 범위를 벗어나거나 현재 글자가 일치하지 않을 때
if (
y < 0 ||
y >= board.length ||
x < 0 ||
x >= board[0].length ||
board[y][x] !== word[index]
) {
return false;
}

// 현재 셀 사용 표시
const temp = board[y][x];
board[y][x] = true; // 임시 방문 표시

// 상하좌우 탐색, 하나라도 찾게된다면 true
const found =
dfs(board, y + 1, x, word, index + 1) ||
dfs(board, y - 1, x, word, index + 1) ||
dfs(board, y, x + 1, word, index + 1) ||
dfs(board, y, x - 1, word, index + 1);

// 원래 값으로 복원 (백트래킹)
board[y][x] = temp;

return found;
}