diff --git a/clone-graph/byol-han.js b/clone-graph/byol-han.js new file mode 100644 index 000000000..9c20dad67 --- /dev/null +++ b/clone-graph/byol-han.js @@ -0,0 +1,37 @@ +/** + * https://leetcode.com/problems/clone-graph/ + * // Definition for a _Node. + * function _Node(val, neighbors) { + * this.val = val === undefined ? 0 : val; + * this.neighbors = neighbors === undefined ? [] : neighbors; + * }; + * 시간 복잡도: O(N) — 노드 수만큼 순회 + * 공간 복잡도: O(N) — visited 맵과 재귀 호출 스택 + */ + +/** + * @param {_Node} node + * @return {_Node} + */ +var cloneGraph = function (node) { + if (!node) return null; + + const visited = new Map(); + + const dfs = (n) => { + if (visited.has(n)) { + return visited.get(n); + } + + const clone = new Node(n.val); + visited.set(n, clone); + + for (let neighbor of n.neighbors) { + clone.neighbors.push(dfs(neighbor)); + } + + return clone; + }; + + return dfs(node); +}; diff --git a/linked-list-cycle/byol-han.js b/linked-list-cycle/byol-han.js new file mode 100644 index 000000000..9071f7be7 --- /dev/null +++ b/linked-list-cycle/byol-han.js @@ -0,0 +1,34 @@ +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} head + * @return {boolean} + */ +var hasCycle = function (head) { + // 리스트가 비어 있거나 노드가 하나뿐이면 사이클이 있을 수 없음 + if (!head || !head.next) return false; + + // 두 포인터 초기화: slow는 한 칸씩, fast는 두 칸씩 이동 + let slow = head; + let fast = head.next; + + // fast와 slow가 만날 때까지 반복 + while (fast !== slow) { + // fast가 끝에 도달하면 사이클이 없음 + if (!fast || !fast.next) return false; + + // slow는 한 칸 이동 + slow = slow.next; + // fast는 두 칸 이동 + fast = fast.next.next; + } + + // fast와 slow가 만났다면 사이클이 있음 + return true; +}; diff --git a/longest-common-subsequence/byol-han.js b/longest-common-subsequence/byol-han.js new file mode 100644 index 000000000..a3afa3191 --- /dev/null +++ b/longest-common-subsequence/byol-han.js @@ -0,0 +1,29 @@ +/** + * https://leetcode.com/problems/longest-common-subsequence/submissions/1644426037/ + * @param {string} text1 + * @param {string} text2 + * @return {number} + */ +var longestCommonSubsequence = function (text1, text2) { + const m = text1.length; + const n = text2.length; + + // Create 2D array initialized with 0 + const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + + // Fill the dp table + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (text1[i - 1] === text2[j - 1]) { + // Characters match + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + // No match, take the max from left or top cell + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + + // The length of the longest common subsequence + return dp[m][n]; +}; diff --git a/maximum-product-subarray/byol-han.js b/maximum-product-subarray/byol-han.js new file mode 100644 index 000000000..5e9b329c8 --- /dev/null +++ b/maximum-product-subarray/byol-han.js @@ -0,0 +1,28 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var maxProduct = function (nums) { + // 최대 곱을 저장할 변수 + let maxProduct = nums[0]; + // 현재 위치까지의 최대 곱과 최소 곱을 저장할 변수 + let currentMax = nums[0]; + let currentMin = nums[0]; + + // 배열의 두 번째 원소부터 순회 + for (let i = 1; i < nums.length; i++) { + const num = nums[i]; + + // 음수를 곱할 경우 최대와 최소가 바뀔 수 있으므로 미리 저장 + const tempMax = currentMax; + + // 현재 숫자와 곱했을 때의 최대/최소 값을 계산 + currentMax = Math.max(num, num * currentMax, num * currentMin); + currentMin = Math.min(num, num * tempMax, num * currentMin); + + // 전체 최대 곱을 업데이트 + maxProduct = Math.max(maxProduct, currentMax); + } + + return maxProduct; +}; diff --git a/palindromic-substrings/byol-han.js b/palindromic-substrings/byol-han.js new file mode 100644 index 000000000..69e7cdd55 --- /dev/null +++ b/palindromic-substrings/byol-han.js @@ -0,0 +1,24 @@ +/** + * https://leetcode.com/problems/palindromic-substrings/submissions/1644425061/ + * @param {string} s + * @return {number} + */ +var countSubstrings = function (s) { + let count = 0; + + // Helper function to expand around the center + function expandAroundCenter(left, right) { + while (left >= 0 && right < s.length && s[left] === s[right]) { + count++; // Found a palindrome + left--; + right++; + } + } + + for (let i = 0; i < s.length; i++) { + expandAroundCenter(i, i); // Odd-length palindromes + expandAroundCenter(i, i + 1); // Even-length palindromes + } + + return count; +}; diff --git a/sum-of-two-integers/byol-han.js b/sum-of-two-integers/byol-han.js new file mode 100644 index 000000000..c6d6cfc23 --- /dev/null +++ b/sum-of-two-integers/byol-han.js @@ -0,0 +1,22 @@ +/** + * https://leetcode.com/problems/sum-of-two-integers/submissions/1649575939/ + * @param {number} a + * @param {number} b + * @return {number} + */ +var getSum = function (a, b) { + while (b !== 0) { + // a와 b의 합에서 자리올림(carry)을 제외한 값 계산 (XOR 연산) + let sum = a ^ b; + + // 자리올림(carry)을 계산 (AND 연산 후 왼쪽으로 한 비트 이동) + let carry = (a & b) << 1; + + // 새로운 a는 sum, 새로운 b는 carry가 됨 + a = sum; + b = carry; + } + + // carry가 0이 되면 더할 게 없으므로 최종 결과 a 반환 + return a; +};