From 9870def8fcf8b2fe2654b9f8440a7561aa880b3d Mon Sep 17 00:00:00 2001 From: mmyeon Date: Fri, 24 Jan 2025 13:22:16 +0900 Subject: [PATCH 1/6] add solution : 191. Number of 1 Bits --- number-of-1-bits/mmyeon.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 number-of-1-bits/mmyeon.ts diff --git a/number-of-1-bits/mmyeon.ts b/number-of-1-bits/mmyeon.ts new file mode 100644 index 000000000..7e2bb2714 --- /dev/null +++ b/number-of-1-bits/mmyeon.ts @@ -0,0 +1,34 @@ +/** + * @link https://leetcode.com/problems/number-of-1-bits/description/ + * + * 접근 방법 : + * - n을 2로 나누면서 나머지가 1인 경우 카운트를 업데이트한다. + * + * 시간복잡도 : O(log(n)) + * - 숫자의 비트 길이만큼 반복 + * + * 공간복잡도 : O(1) + * - 고정된 변수만 사용 + */ +function hammingWeight(n: number): number { + let bitCount = 0; + while (n >= 1) { + bitCount += n % 2; + + n = Math.floor(n / 2); + } + + return bitCount; +} + +// 비트 연산자 활용하는 방법 +function hammingWeight(n: number): number { + let bitCount = 0; + while (n >= 1) { + bitCount += n & 1; + + n >>>= 1; + } + + return bitCount; +} From aca55c4d29e1124aa6892f78915064997455bbf8 Mon Sep 17 00:00:00 2001 From: mmyeon Date: Tue, 28 Jan 2025 23:38:08 +0900 Subject: [PATCH 2/6] add solution : 371. Sum of Two Integers --- sum-of-two-integers/mmyeon.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 sum-of-two-integers/mmyeon.ts diff --git a/sum-of-two-integers/mmyeon.ts b/sum-of-two-integers/mmyeon.ts new file mode 100644 index 000000000..6330f0067 --- /dev/null +++ b/sum-of-two-integers/mmyeon.ts @@ -0,0 +1,29 @@ +/** + *@link https://leetcode.com/problems/sum-of-two-integers/description/ + * + * 접근 방법 : + * - 비트 AND 연산자(&) 사용해서 자리 올림이 필요한 비트 계산하고 왼쪽 시트트로 자리 올림값을 다음 자리로 이동 + * - 비트 XOR 연산자(^) 사용해서 자리 올림 제외한 자리합 계산하고 a값 업데이트 + * - 자리 올림값이 0이 될 때까지 자리 올림 반복 + * - 자리 올림 없으면 최종합이 저장된 a 리턴 + * + * + * 시간복잡도 : O(k) + * - k는 숫자의 비트 수, 최대 k번 반복 + * + * 공간복잡도 : O(1) + * - 고정된 변수만 사용 + * + */ + +function getSum(a: number, b: number): number { + while (b) { + // 자리 올림 계산 + const carry = (a & b) << 1; + // 자리합 업데이트 (같은 비트 = 0, 다른 비트 = 1) + a ^= b; + b = carry; + } + + return a; +} From e7f87d0e916d4464b143af8907b1f95d735f7fcd Mon Sep 17 00:00:00 2001 From: mmyeon Date: Tue, 28 Jan 2025 23:48:55 +0900 Subject: [PATCH 3/6] update comment --- number-of-1-bits/mmyeon.ts | 8 ++++++-- sum-of-two-integers/mmyeon.ts | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/number-of-1-bits/mmyeon.ts b/number-of-1-bits/mmyeon.ts index 7e2bb2714..b3f87fa03 100644 --- a/number-of-1-bits/mmyeon.ts +++ b/number-of-1-bits/mmyeon.ts @@ -4,7 +4,7 @@ * 접근 방법 : * - n을 2로 나누면서 나머지가 1인 경우 카운트를 업데이트한다. * - * 시간복잡도 : O(log(n)) + * 시간복잡도 : O(logn) * - 숫자의 비트 길이만큼 반복 * * 공간복잡도 : O(1) @@ -21,7 +21,11 @@ function hammingWeight(n: number): number { return bitCount; } -// 비트 연산자 활용하는 방법 +/** + * 접근 방법 : 비트 연산자 활용 + * - n & 1 : n의 마지막 비트가 1인지 확인하여 bitCount 업데이트 + * - n >>>= 1 : 오른쪽 시프트로 n을 1비트씩 이동 + */ function hammingWeight(n: number): number { let bitCount = 0; while (n >= 1) { diff --git a/sum-of-two-integers/mmyeon.ts b/sum-of-two-integers/mmyeon.ts index 6330f0067..cf809e8f6 100644 --- a/sum-of-two-integers/mmyeon.ts +++ b/sum-of-two-integers/mmyeon.ts @@ -2,7 +2,7 @@ *@link https://leetcode.com/problems/sum-of-two-integers/description/ * * 접근 방법 : - * - 비트 AND 연산자(&) 사용해서 자리 올림이 필요한 비트 계산하고 왼쪽 시트트로 자리 올림값을 다음 자리로 이동 + * - 비트 AND 연산자(&) 사용해서 자리 올림이 필요한 비트 계산하고 왼쪽 시프트(<<)로 자리 올림값을 다음 자리로 이동 * - 비트 XOR 연산자(^) 사용해서 자리 올림 제외한 자리합 계산하고 a값 업데이트 * - 자리 올림값이 0이 될 때까지 자리 올림 반복 * - 자리 올림 없으면 최종합이 저장된 a 리턴 From d9b9c429394d234f4d9bf203aa09479e9216b2a7 Mon Sep 17 00:00:00 2001 From: mmyeon Date: Fri, 31 Jan 2025 13:56:16 +0900 Subject: [PATCH 4/6] add solution : 1143. Longest Common Subsequence --- longest-common-subsequence/mmyeon.ts | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 longest-common-subsequence/mmyeon.ts diff --git a/longest-common-subsequence/mmyeon.ts b/longest-common-subsequence/mmyeon.ts new file mode 100644 index 000000000..9d3ca967e --- /dev/null +++ b/longest-common-subsequence/mmyeon.ts @@ -0,0 +1,31 @@ +/** + * @link https://leetcode.com/problems/longest-common-subsequence/description/ + * + * 접근 방법 : + * - LCS 길이 담을 DP 배열 선언 + * - 문자 순회하면서 같은 문자인 경우, 이전 값 + 1 로 업데이트 + * - 문자 다른 경우, 이전 값 그대로 유지 + * + * 시간복잡도 : O(m * n) + * - 두 문자열 길이 크기만큼 이중 반복문 실행 + * + * 공간복잡도 : O(m * n) + * - 두 문자 길이 크기만큼 DP 배열에 저장 + */ +function longestCommonSubsequence(text1: string, text2: string): number { + const m = text1.length, + n = text2.length; + + const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); + + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + if (text1[i - 1] === text2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + } + return dp[m][n]; +} From f62904de6bb59ddcf01f288590fd3499990d6325 Mon Sep 17 00:00:00 2001 From: mmyeon Date: Fri, 31 Jan 2025 15:09:49 +0900 Subject: [PATCH 5/6] add solution : 133. Clone Graph --- clone-graph/mmyeon.ts | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 clone-graph/mmyeon.ts diff --git a/clone-graph/mmyeon.ts b/clone-graph/mmyeon.ts new file mode 100644 index 000000000..5a18d0f8d --- /dev/null +++ b/clone-graph/mmyeon.ts @@ -0,0 +1,48 @@ +class _Node { + val: number; + neighbors: _Node[]; + constructor(val?: number, neighbors?: _Node[]) { + this.val = val === undefined ? 0 : val; + this.neighbors = neighbors === undefined ? [] : neighbors; + } +} + +/** + * @link https://leetcode.com/problems/clone-graph/description/ + * + * 접근 방법 : + * - 엣지 케이스 : 주어진 노드가 null이면 그대로 리턴 + * - 이미 방문한 노드인지 확인 : 방문한 노드인 경우, 저장된 복사 노드 리턴해서 중복 생성 방지 + * - 새로운 노드 클론하고 visited 맵에 저장 + * - 해당 노드의 이웃 노드도 순회하면서 복제 + * - 클론된 노드 리턴 + * + * 시간복잡도 : O(n + e) + * - n은 노드의 개수, e는 노드 연결하는 엣지의 개수 + * - 모든 노드 순회하면서 각 노드의 이웃 탐색 + * + * 공간복잡도 : O(n) + * - 모든 노드를 클론해서 visited 맵에 저장되므로 O(n) + * - 그래프가 선형 구조인 최악의 경우, 재귀 호출 스택이 O(n) + */ +function cloneGraph(node: _Node | null): _Node | null { + if (!node) return null; + const visited = new Map(); + + const cloneNode = (node: _Node): _Node => { + if (visited.has(node.val)) return visited.get(node.val) as _Node; + + const clonedNode = new _Node(node.val); + visited.set(node.val, clonedNode); + + for (const neighbor of node.neighbors) { + const clonedNeighbor = cloneNode(neighbor); + + clonedNode.neighbors.push(clonedNeighbor); + } + + return clonedNode; + }; + + return cloneNode(node); +} From 95e49affca2724abdf852f3cf4de4626998fce43 Mon Sep 17 00:00:00 2001 From: mmyeon Date: Fri, 31 Jan 2025 16:50:14 +0900 Subject: [PATCH 6/6] add solution : 424. Longest Repeating Character Replacement --- .../mmyeon.ts | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 longest-repeating-character-replacement/mmyeon.ts diff --git a/longest-repeating-character-replacement/mmyeon.ts b/longest-repeating-character-replacement/mmyeon.ts new file mode 100644 index 000000000..b339096c1 --- /dev/null +++ b/longest-repeating-character-replacement/mmyeon.ts @@ -0,0 +1,39 @@ +/** + * @link https://leetcode.com/problems/longest-repeating-character-replacement/ + * + * 접근 방법 : + * - 문자열 순회하면서, 현재 윈도우 내 문자의 빈도수 저장 + * - 윈도우 축소 조건 : 윈도우 크기 - 윈도우 내 최다 등장 문자의 개수 > k + * => k보다 다른 문자의 개수가 많은 경우, left 포인터 이동해서 윈도우 크기 줄이기 + * - 윈도우 크기 조절하면서 최대 길이 업데이트 + * + * 시간복잡도 : O(n) + * - 문자 n개만큼 1회 순회하면서 윈도우 크기 조절 + * + * 공간복잡도 : O(1) + * - 대문자의 개수(26개)만큼 map에 저장 + */ +function characterReplacement(s: string, k: number): number { + const map = new Map(); + let maxFrequency = 0, + maxLength = 0, + left = 0; + + for (let right = 0; right < s.length; right++) { + const rightPositionChar = s[right]; + // 문자의 빈도수 map에 저장 + map.set(rightPositionChar, (map.get(rightPositionChar) ?? 0) + 1); + maxFrequency = Math.max(maxFrequency, map.get(rightPositionChar)!); + + // 윈도우 축소해야 되는 경우 - k보다 다른 문자의 개수가 많은 경우 + if (right - left + 1 - maxFrequency > k) { + map.set(s[left], map.get(s[left])! - 1); + left++; + } + + // 최대 길이 업데이트 + maxLength = Math.max(maxLength, right - left + 1); + } + + return maxLength; +}