diff --git a/coin-change/krokerdile.js b/coin-change/krokerdile.js new file mode 100644 index 000000000..e8ba2bdbc --- /dev/null +++ b/coin-change/krokerdile.js @@ -0,0 +1,25 @@ +/** + * @param {number[]} coins + * @param {number} amount + * @return {number} + */ +var coinChange = function(coins, amount) { + const dp = new Array(amount + 1).fill(Infinity); + dp[0] = 0; // 0원을 만들기 위한 동전 수는 0개 + + // bottom-up DP + for (let i = 1; i <= amount; i++) { + for (const coin of coins) { + if (i - coin >= 0) { + dp[i] = Math.min(dp[i], dp[i - coin] + 1); + } + } + } + + return dp[amount] === Infinity ? -1 : dp[amount]; +}; + +// 시간복잡도: O(amount * coins.length) +// -> 각 금액 i마다 모든 coin을 시도하기 때문 +// 공간복잡도: O(amount) +// -> dp 배열을 사용하기 때문 diff --git a/find-minimum-in-rotated-sorted-array/krokerdile.js b/find-minimum-in-rotated-sorted-array/krokerdile.js new file mode 100644 index 000000000..b692dfcdf --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/krokerdile.js @@ -0,0 +1,26 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var findMin = function(nums) { + let left = 0; + let right = nums.length - 1; + + while (left < right) { + const mid = Math.floor((left + right) / 2); + + // 중간값이 오른쪽보다 크면 최소값은 오른쪽에 있다! + if (nums[mid] > nums[right]) { + left = mid + 1; + } else { + // 최소값은 mid를 포함한 왼쪽에 있다! + right = mid; + } + } + + // left == right일 때 최소값이 위치함 + return nums[left]; +}; + +// 시간 복잡도: O(log n), 이진 탐색으로 탐색 범위를 절반씩 줄여나감 +// 공간 복잡도: O(1), 추가적인 공간을 사용하지 않음 diff --git a/maximum-depth-of-binary-tree/krokerdile.js b/maximum-depth-of-binary-tree/krokerdile.js new file mode 100644 index 000000000..4234c561a --- /dev/null +++ b/maximum-depth-of-binary-tree/krokerdile.js @@ -0,0 +1,30 @@ +/** + * 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 === null) return 0; + + let queue = [root]; + let depth = 0; + + while (queue.length > 0) { + let levelSize = queue.length; + for (let i = 0; i < levelSize; i++) { + const node = queue.shift(); + if (node.left) queue.push(node.left); + if (node.right) queue.push(node.right); + } + depth++; + } + + return depth; +}; diff --git a/merge-two-sorted-lists/krokerdile.js b/merge-two-sorted-lists/krokerdile.js new file mode 100644 index 000000000..f59df2284 --- /dev/null +++ b/merge-two-sorted-lists/krokerdile.js @@ -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) { + // 결과 리스트의 시작점을 위한 더미 노드 + let dummy = new ListNode(-1); + let current = dummy; + + // 둘 다 null이 아닐 때까지 반복 + while (list1 !== null && list2 !== null) { + if (list1.val <= list2.val) { + current.next = list1; + list1 = list1.next; + } else { + current.next = list2; + list2 = list2.next; + } + current = current.next; + } + + // 남은 노드가 있으면 그대로 붙임 + current.next = list1 !== null ? list1 : list2; + + return dummy.next; // dummy 다음이 진짜 head +}; diff --git a/word-search/krokerdile.js b/word-search/krokerdile.js new file mode 100644 index 000000000..29eaa57c5 --- /dev/null +++ b/word-search/krokerdile.js @@ -0,0 +1,47 @@ +/** + * @param {character[][]} board + * @param {string} word + * @return {boolean} + */ +var exist = function(board, word) { + const rows = board.length; + const cols = board[0].length; + + // DFS 함수 정의 + const dfs = (r, c, idx) => { + // 단어 끝까지 찾은 경우 + if (idx === word.length) return true; + + // 범위 밖이거나, 문자 불일치거나, 이미 방문한 경우 + if ( + r < 0 || c < 0 || r >= rows || c >= cols || + board[r][c] !== word[idx] + ) { + return false; + } + + const temp = board[r][c]; // 현재 문자 저장 + board[r][c] = "#"; // 방문 표시 + + // 상하좌우로 탐색 + const found = dfs(r + 1, c, idx + 1) || + dfs(r - 1, c, idx + 1) || + dfs(r, c + 1, idx + 1) || + dfs(r, c - 1, idx + 1); + + board[r][c] = temp; // 백트래킹: 원상복구 + + return found; + }; + + // 보드의 모든 칸에서 시작해보기 + for (let r = 0; r < rows; r++) { + for (let c = 0; c < cols; c++) { + if (dfs(r, c, 0)) return true; + } + } + + return false; +}; + +// 시간복잡도: O(m * n * 4^L), m*n번 DFS 시작 가능하고, 각 DFS는 최대 4방향 * 단어 길이 만큼 탐색