From 97c6d2a5d685b2b5fd0b02d999612e8218e8f56d Mon Sep 17 00:00:00 2001 From: Youngjae Kim Date: Sun, 29 Dec 2024 21:52:51 +0900 Subject: [PATCH 1/6] add: solve #224 Merge Two Sorted Lists with ts --- merge-two-sorted-lists/Yjason-K.ts | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 merge-two-sorted-lists/Yjason-K.ts diff --git a/merge-two-sorted-lists/Yjason-K.ts b/merge-two-sorted-lists/Yjason-K.ts new file mode 100644 index 000000000..d0cce4804 --- /dev/null +++ b/merge-two-sorted-lists/Yjason-K.ts @@ -0,0 +1,49 @@ +class ListNode { + val: number + next: ListNode | null + constructor(val?: number, next?: ListNode | null) { + this.val = (val===undefined ? 0 : val) + this.next = (next===undefined ? null : next) + } +} + +/** + * 두 개의 정렬된 연결 리스트를 병합하여 하나의 정렬된 연결 리스트를 반환하는 함수 + * @param {ListNode | null} list1 - 첫 번째 정렬된 연결 리스트 + * @param {ListNode | null} list2 - 두 번째 정렬된 연결 리스트 + * @returns {ListNode | null} - 병합된 정렬된 연결 리스트 + * + * 시간 복잡도: O(n + m) + * - n: list1의 노드 개수 + * - m: list2의 노드 개수 + * + * 공간 복잡도: O(1) + * - 새로운 노드를 생성하지 않고 기존 노드의 포인터를 조정하여 병합하므로 추가 공간 사용 없음 + */ + +function mergeTwoLists(list1: ListNode | null, list2: ListNode | null): ListNode | null { + // null 예외 처리 + if (!list1 || !list2) return list1 || list2; + + // 시작점을 위한 더미 헤드 노드 생성 + const start = new ListNode(-101); + let current = start; + + // 두 리스트를 순차적으로 비교하며 병합 + 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; + } + + // 남은 노드를 연결 (list1 또는 list2 중 하나는 null 상태) + current.next = list1 !== null ? list1 : list2; + + // 더미 헤드의 다음 노드가 실제 병합된 리스트의 시작 + return start.next; +} From 38f0f15d40e696d727c155aaeec93f8d59562b02 Mon Sep 17 00:00:00 2001 From: Youngjae Kim Date: Mon, 30 Dec 2024 23:39:29 +0900 Subject: [PATCH 2/6] add: solve #235 Missing Number with ts --- missing-number/Yjason-K.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 missing-number/Yjason-K.ts diff --git a/missing-number/Yjason-K.ts b/missing-number/Yjason-K.ts new file mode 100644 index 000000000..83501be6e --- /dev/null +++ b/missing-number/Yjason-K.ts @@ -0,0 +1,29 @@ +/** + * 0부터 n까지의 숫자 중 배열에서 누락된 숫자를 찾는 함수 + * @param {number[]} nums - 0부터 n까지의 숫자가 포함된 배열 (순서는 무작위이며 일부 숫자가 누락될 수 있음) + * @returns {number} - 배열에서 누락된 숫자 + * + * 시간 복잡도: O(n) + * - Set은 Hash Table로 구현되어 has 메서드가 Array.includes 메서드보다 유리 + * - Set을 생성하는 데 O(n) 시간이 소요 + * - 배열 길이만큼 반복문을 돌면서 Set의 존재 여부를 확인하는 데 O(1) * n = O(n) + * - 결과적으로 O(n) + O(n) = O(n) + * + * 공간 복잡도: O(n) + * - Set 자료구조를 사용하여 입력 배열의 모든 요소를 저장하므로 O(n)의 추가 메모리 사용 + */ +function missingNumber(nums: number[]): number { + // 배열의 숫자를 모두 Set에 추가하여 중복 제거 + const distinctSet = new Set([...nums]); + + // 0부터 n까지의 숫자 중에서 누락된 숫자를 탐색 + for (let i = 0; i < nums.length; i++) { + // Set에 i가 존재하지 않으면 i가 누락된 숫자 + if (!distinctSet.has(i)) { + return i; + } + } + + // 모든 숫자가 Set에 존재하면 n이 누락된 숫자 + return nums.length; +} From faf89d9feb4734b7175eda34c802c194c81692ef Mon Sep 17 00:00:00 2001 From: Youngjae Kim Date: Tue, 31 Dec 2024 20:28:10 +0900 Subject: [PATCH 3/6] add: solve #255 Word Search with ts --- word-search/Yjason-K.ts | 70 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 word-search/Yjason-K.ts diff --git a/word-search/Yjason-K.ts b/word-search/Yjason-K.ts new file mode 100644 index 000000000..de11f48a3 --- /dev/null +++ b/word-search/Yjason-K.ts @@ -0,0 +1,70 @@ +/** + * board 에서 주어진 단어를 찾을 수 있는지 여부 확인 (boolean) + * @param {string[][]} board - 단어를 탐색할 2D board + * @param {string} word - 찾고자 하는 단어 + * @returns {boolean} - 단어가 격자에서 존재하면 true, 그렇지 않으면 false + * + * 시간 복잡도: O(N * M * 4^L) + * - N: board의 행 개수 + * - M: board의 열 개수 + * - L: word의 길이 + * + * 공간 복잡도: O(L) (재귀 호출 스택) + */ +function exist(board: string[][], word: string): boolean { + const rows = board.length; + const cols = board[0].length; + + // 방향 배열 (상, 하, 좌, 우) + const directions = [ + [0, -1], // 상 + [0, 1], // 하 + [-1, 0], // 좌 + [1, 0], // 우 + ]; + + /** + * DFS 탐색(깊이 우선 탐색)을 통해 단어를 찾는 함수 + * @param {number} x - 현재 x 좌표 (열) + * @param {number} y - 현재 y 좌표 (행) + * @param {number} index - 현재 탐색 중인 word의 문자 인덱스 + * @returns {boolean} - 현재 경로가 유효하면 true, 유효하지 않으면 false + */ + const dfs = (x: number, y: number, index: number): boolean => { + // 단어를 모두 찾았을 경우 + if (index === word.length) return true; + + // 범위를 벗어나거나 문자가 일치하지 않는 경우 + if (x < 0 || y < 0 || x >= cols || y >= rows || board[y][x] !== word[index]) { + return false; + } + + // 현재 위치 방문 처리 (임시 수정) + const temp = board[y][x]; + board[y][x] = "#"; + + // 상하좌우 탐색 + for (const [dx, dy] of directions) { + if (dfs(x + dx, y + dy, index + 1)) { + return true; + } + } + + // 백트래킹: 셀 값 복구 + board[y][x] = temp; + + return false; + }; + + // board에서 word 첫글자가 일치하는 경우 탐색 시작 + for (let y = 0; y < rows; y++) { + for (let x = 0; x < cols; x++) { + if (board[y][x] === word[0] && dfs(x, y, 0)) { + return true; + } + } + } + + return false; +} + From bf38b87418a908c8fa4893bcac3d9401d6727573 Mon Sep 17 00:00:00 2001 From: Youngjae Kim Date: Wed, 1 Jan 2025 15:43:13 +0900 Subject: [PATCH 4/6] add: solve #267 Palindromic Substrings with ts --- palindromic-substrings/Yjason-K.ts | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 palindromic-substrings/Yjason-K.ts diff --git a/palindromic-substrings/Yjason-K.ts b/palindromic-substrings/Yjason-K.ts new file mode 100644 index 000000000..9405bff4f --- /dev/null +++ b/palindromic-substrings/Yjason-K.ts @@ -0,0 +1,48 @@ +/** + * 문자열에서 substring 중 panlindrome인 경우의 수를 구하는 함수 + * @param {string} s - 입력 문자열 + * @returns {number} - s문자열에서 찾을수 있는 panlindrome substring의 개수 + * + * 시간 복잡도: O(n^2) (n: 문자열 길이) + * - 한 번의 외부 루프: 부분 문자열 길이 (\(subLen\)) - O(n) + * - 내부 루프: 시작 인덱스 (\(start\)) - O(n) + * - 따라서, 총 복잡도는 O(n^2) + * + * 공간 복잡도: O(n^2) + * - DP 배열 dp[i][j]는 \(n^2\) 크기를 가지며 문자열의 모든 시작과 끝 조합에 대한 정보를 저장합니다. + */ +function countSubstrings(s: string): number { + const n = s.length; // 문자열 길이 + let result = 0; + + // DP 배열 생성 (dp[i][j] 는 s[i] ~ s[j] 까지가 회문인지 여부를 저장) + const dp: boolean[][] = Array.from({ length: n }, () => Array(n).fill(false)); + + // 1글자 경우 + for (let i = 0; i < n; i++) { + dp[i][i] = true; + result++; + } + + // 2글자 경우 + for (let i = 0; i < n - 1; i++) { + if (s[i] === s[i + 1]) { + dp[i][i + 1] = true; + result++; + } + } + + // 3글자 이상인 경우 + for (let subLen = 3; subLen <= n; subLen++) { + for (let start = 0; start <= n - subLen; start++) { + const end = start + subLen - 1; + // 양 끝 문자가 같고, 내부 부분 문자열이 회문이면 true + if (s[start] === s[end] && dp[start + 1][end - 1]) { + dp[start][end] = true; + result++; + } + } + } + + return result; +} From 127f9a69358ef7de8aaf88b2050915d9408340f5 Mon Sep 17 00:00:00 2001 From: Youngjae Kim Date: Thu, 2 Jan 2025 22:36:30 +0900 Subject: [PATCH 5/6] add: solve #269 Coin Change with ts --- coin-change/Yjason-K.ts | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 coin-change/Yjason-K.ts diff --git a/coin-change/Yjason-K.ts b/coin-change/Yjason-K.ts new file mode 100644 index 000000000..28a87bc75 --- /dev/null +++ b/coin-change/Yjason-K.ts @@ -0,0 +1,45 @@ +/** + * 가지고 있는 동전을 최대한 활용하여 최소의 조합으로 amount를 만드는 최소 동전 개수 구하는 함수 + * + * @param {number[]} coins - 사용 가능한 동전 배열 + * @param {number} amount - 만들어야 하는 총합 + * @returns {number} + * + * 시간 복잡도 O(n * m) + * - n은 동전 배열의 크기 + * - m은 amount + * + * 공간 복잡도 (n); + * - 큐에 최대 n개의 요소가 들어갈 수 있음 + */ +function coinChange(coins: number[], amount: number): number { + // 총합이 0인 경우 0 반환 + if (amount === 0) return 0; + + // 너비 우선 탐색을 활용한 풀이 + + const queue: [number, number] [] = [[0, 0]]; // [현재 총합, 깊이] + const visited = new Set(); + + while (queue.length > 0) { + const [currentSum, depth] = queue.shift()!; + + // 동전을 하나씩 더해서 다음 깊이을 탐색 + for (const coin of coins) { + const nextSum = currentSum + coin; + + // 목표 금액에 도달하면 현재 깊이를 반환 + if (nextSum === amount) return depth + 1; + + // 아직 총합에 도달하지 않았고, 중복되지 않아 탐색 가능한 경우 + if (nextSum < amount && !visited.has(nextSum)) { + queue.push([nextSum, depth + 1]); + visited.add(nextSum) + } + + } + } + + // 탐색 조건을 완료 해도 경우의 수를 찾지 못한 경우 + return -1; +} \ No newline at end of file From 07fa57921c4c52b54c4e5c05e5d755990cbacd93 Mon Sep 17 00:00:00 2001 From: Youngjae Kim Date: Thu, 2 Jan 2025 22:43:53 +0900 Subject: [PATCH 6/6] add: fix #829 line break --- coin-change/Yjason-K.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/coin-change/Yjason-K.ts b/coin-change/Yjason-K.ts index 28a87bc75..46531901c 100644 --- a/coin-change/Yjason-K.ts +++ b/coin-change/Yjason-K.ts @@ -42,4 +42,5 @@ function coinChange(coins: number[], amount: number): number { // 탐색 조건을 완료 해도 경우의 수를 찾지 못한 경우 return -1; -} \ No newline at end of file +} +