diff --git a/coin-change/moonjonghoo.js b/coin-change/moonjonghoo.js new file mode 100644 index 000000000..eeae23d8d --- /dev/null +++ b/coin-change/moonjonghoo.js @@ -0,0 +1,28 @@ +/** + * πŸ”’ 문제 이름: coin-change + * 🧩 문제 μœ ν˜•: dp + * πŸ’‘ 핡심 아이디어 + * - κΈˆμ•‘ iλ₯Ό λ§Œλ“€ 수 μžˆλŠ” μ΅œμ†Œ 동전 수λ₯Ό dp[i]에 μ €μž₯ + * - ν•˜μœ„ 문제 dp[i - coin]μ—μ„œ 1개λ₯Ό μΆ”κ°€ν•˜λŠ” 방식 + * - dp[0] = 0을 μ‹œμž‘μœΌλ‘œ bottom-up λ°©μ‹μœΌλ‘œ 점화식을 μ±„μ›Œλ‚˜κ°„λ‹€ + * + * πŸ“ˆ μ‹œκ°„λ³΅μž‘λ„: O(n * k) β€” n = amount, k = coins.length + * πŸ“¦ κ³΅κ°„λ³΅μž‘λ„: O(n) + */ + +function coinChange(coins, amount) { + //1. dp 배열을 μ„€μ •ν•©λ‹ˆλ‹€. + const dp = new Array(amount + 1).fill(Infinity); + dp[0] = 0; + //2. νƒμƒ‰ν•˜μ—¬ μ΅œμ†Œλ™μ „μ˜ 개수λ₯Ό 담은 dp배열을 μ±„μ›λ‹ˆλ‹€. + for (let i = 1; i <= amount; i++) { + for (let coin of coins) { + //코인을 μ‚¬μš©κ°€λŠ₯ν•˜λ‹€λ©΄, 비ꡐꡐ + if (i - coins >= 0) { + dp[i] = Math.min(dp[i], dp[i - coin] + 1); + } + } + } + // 3. amount 값이 Infinity 라면 λΆˆκ°€λŠ₯ν•˜λ‹€λΌλŠ” μ˜λ―ΈκΈ°λ–„λ¬Έμ— -1 리턴턴 + return dp[amount] === Infinity ? -1 : dp[amount]; +} diff --git a/find-minimum-in-rotated-sorted-array/moonjonghoo.js b/find-minimum-in-rotated-sorted-array/moonjonghoo.js new file mode 100644 index 000000000..9cc36295d --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/moonjonghoo.js @@ -0,0 +1,17 @@ +/** + * @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]; +}; diff --git a/merge-two-sorted-lists/moonjonghoo.js b/merge-two-sorted-lists/moonjonghoo.js new file mode 100644 index 000000000..b716f5ca5 --- /dev/null +++ b/merge-two-sorted-lists/moonjonghoo.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) { + // 1) κ°€μ§œ μ‹œμž‘μ (dummy)κ³Ό current 포인터 생성 + const dummy = new ListNode(-1); + let current = dummy; + + // 2) 두 리슀트 λͺ¨λ‘ 남아 μžˆλŠ” λ™μ•ˆ 더 μž‘μ€ λ…Έλ“œλ₯Ό μ—°κ²° + while (list1 && list2) { + if (list1.val < list2.val) { + current.next = list1; + list1 = list1.next; + } else { + current.next = list2; + list2 = list2.next; + } + current = current.next; + } + + // 3) 남은 λ…Έλ“œλ₯Ό ν•œ λ²ˆμ— 이어뢙이고, κ²°κ³Ό λ°˜ν™˜ + current.next = list1 || list2; + return dummy.next; +}; diff --git a/word-search/moonjonghoo.js b/word-search/moonjonghoo.js new file mode 100644 index 000000000..20fdd5757 --- /dev/null +++ b/word-search/moonjonghoo.js @@ -0,0 +1,77 @@ +/** + * πŸ”’ 문제 이름: Word Search (LeetCode 79) + * 🧩 문제 μœ ν˜•: DFS + Backtracking + * + * 🎯 문제 μ„€λͺ…: + * μ£Όμ–΄μ§„ 2차원 문자 격자(board)와 λ¬Έμžμ—΄(word)μ—μ„œ, + * 단어가 board μ•ˆμ—μ„œ μΈμ ‘ν•œ μ…€(μƒν•˜μ’Œμš°)을 톡해 μ‘΄μž¬ν•˜λŠ”μ§€λ₯Ό νŒλ³„ν•˜λΌ. + * 각 셀은 ν•œ 번만 μ‚¬μš©ν•  수 있으며, λŒ€κ°μ„  이동은 ν—ˆμš©λ˜μ§€ μ•ŠλŠ”λ‹€. + * + * πŸ’‘ 핡심 아이디어: + * - λͺ¨λ“  셀을 μ‹œμž‘μ μœΌλ‘œ μ‚Όμ•„ DFS 탐색 + * - ν˜„μž¬ λ¬Έμžκ°€ μΌμΉ˜ν•˜λ©΄ λ‹€μŒ 문자둜 μž¬κ·€ 호좜 + * - visited 배열을 톡해 쀑볡 방문을 λ°©μ§€ + * - DFS 쀑 μ™„μ„±λœ κ²½λ‘œκ°€ 있으면 true λ°˜ν™˜ + * + * πŸ“ˆ μ‹œκ°„λ³΅μž‘λ„: O(N * 3^L) + * - N = 전체 μ…€ 수, L = 단어 길이 + * - 각 μ…€λ§ˆλ‹€ μ΅œλŒ€ 3 λ°©ν–₯으둜 탐색 (이전 μ…€ μ œμ™Έ) + * + * πŸ“¦ κ³΅κ°„λ³΅μž‘λ„: O(L) β€” DFS μž¬κ·€ 깊이 (단어 길이) + */ + +function exist(board, word) { + const rows = board.length; + const cols = board[0].length; + + // 1. visited λ°°μ—΄ μ΄ˆκΈ°ν™” + const visited = Array.from({ length: rows }, () => Array(cols).fill(false)); + + // 2. DFS ν•¨μˆ˜ μ •μ˜ + function dfs(x, y, idx) { + // λͺ¨λ“  문자λ₯Ό μ°Ύμ•˜μœΌλ©΄ 성곡 + if (idx === word.length) return true; + + // λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜κ±°λ‚˜, 이미 λ°©λ¬Έν–ˆκ±°λ‚˜, 문자 뢈일치 β†’ μ‹€νŒ¨ + if ( + x < 0 || + x >= rows || + y < 0 || + y >= cols || + visited[x][y] || + board[x][y] !== word[idx] + ) + return false; + + // ν˜„μž¬ μœ„μΉ˜ λ°©λ¬Έ 처리 + visited[x][y] = true; + + // μƒν•˜μ’Œμš° λ°©ν–₯ μ •μ˜ + const directions = [ + [1, 0], + [-1, 0], + [0, 1], + [0, -1], + ]; + + // 3. λ‹€μŒ 문자 탐색 + for (let [dx, dy] of directions) { + if (dfs(x + dx, y + dy, idx + 1)) return true; + } + + // 4. λ°±νŠΈλž˜ν‚Ή (λ°©λ¬Έ μƒνƒœ 볡원) + visited[x][y] = false; + return false; + } + + // 5. λͺ¨λ“  μ…€μ—μ„œ DFS μ‹œμž‘ μ‹œλ„ + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + if (board[i][j] === word[0] && dfs(i, j, 0)) { + return true; + } + } + } + + return false; +}