Skip to content

Commit 56f2013

Browse files
authored
Merge pull request #1283 from Jeehay28/main
[Jeehay28] WEEK 03 solutions
2 parents e16200e + 96b184f commit 56f2013

File tree

5 files changed

+320
-0
lines changed

5 files changed

+320
-0
lines changed

combination-sum/Jeehay28.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Approach 2: Dynamic Programming
2+
// ✅ Time Complexity: O(N * T * K)
3+
// ✅ Space Complexity: O(T * K)
4+
// N = Number of candidates, T = target, K = average number of combination for each dp[i]
5+
6+
function combinationSum(candidates: number[], target: number): number[][] {
7+
// candidates = [2, 3]
8+
// target = 5
9+
// dp = [
10+
// [[]], // dp[0]
11+
// [], // dp[1]
12+
// [[2]], // dp[2]
13+
// [], // dp[3]
14+
// [[2, 2]], // dp[4]
15+
// [] // dp[5]
16+
// ];
17+
18+
// dp = [
19+
// [[]], // dp[0]
20+
// [], // dp[1]
21+
// [[2]], // dp[2]
22+
// [[3]], // dp[3]
23+
// [[2, 2]], // dp[4]
24+
// [[2, 3]] // dp[5]
25+
// ];
26+
27+
const dp: number[][][] = Array.from({ length: target + 1 }, () => []);
28+
// each element in dp is an independent array, and modifying one will not affect others.
29+
dp[0] = [[]];
30+
31+
for (const candidate of candidates) {
32+
for (let num = candidate; num <= target; num++) {
33+
for (const combination of dp[num - candidate]) {
34+
dp[num].push([...combination, candidate]);
35+
}
36+
}
37+
}
38+
39+
return dp[target];
40+
}
41+
42+
// Approach 1: DFS + Backtracking (Recursive)
43+
// ✅ Time Complexity: O(N^(T / min))
44+
// ✅ Space Complexity: O(K + target / min)
45+
// If target = 7 and smallest number is 2, recursion can go up to 7 / 2 = levels deep
46+
// N = number of candidates, T = target value, K = total number of valid combination found
47+
48+
// function combinationSum(candidates: number[], target: number): number[][] {
49+
// // input:
50+
// // 1) an array of distinct integers
51+
// // 2) a target integer
52+
53+
// // output:
54+
// // a list of all unique combinations of candinates where the chosen numbers sum to target(in any order)
55+
// // duplicated numbers allowed
56+
57+
// let result: number[][] = [];
58+
// let nums: number[] = [];
59+
60+
// const dfs = (start: number, total: number) => {
61+
// if (total > target) {
62+
// return;
63+
// }
64+
65+
// if (total === target) {
66+
// result.push([...nums]);
67+
// return;
68+
// }
69+
70+
// for (let i = start; i < candidates.length; i++) {
71+
// if (total + nums[i] <= target) {
72+
// nums.push(candidates[i]);
73+
// dfs(i, total + candidates[i]);
74+
// nums.pop(); // backtrack
75+
// }
76+
// }
77+
// };
78+
79+
// dfs(0, 0);
80+
81+
// return result;
82+
// }

decode-ways/Jeehay28.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// Approach 4:
2+
// Time Complexity: O(n)
3+
// ✅ Space Complexity: O(1)
4+
5+
function numDecodings(s: string): number {
6+
// s: 2 2 6
7+
// dp: ? ? 1
8+
// cur nxt
9+
10+
let next = 0,
11+
current = 1;
12+
13+
for (let start = s.length - 1; start >= 0; start--) {
14+
const temp = current;
15+
16+
if (s[start] === "0") {
17+
// dp[start] = 0
18+
current = 0;
19+
next = temp;
20+
} else if (
21+
start + 1 < s.length &&
22+
parseInt(s.substring(start, start + 2)) < 27
23+
) {
24+
// dp[start] = dp[start + 1] + dp[start + 2]
25+
current = current + next;
26+
next = temp;
27+
} else {
28+
// dp[start] = dp[start + 1]
29+
next = temp;
30+
}
31+
}
32+
return current;
33+
}
34+
35+
36+
// Approach 3: Dynamic Programming
37+
// Time Complexity: O(n)
38+
// Space Complexity: O(n)
39+
40+
// function numDecodings(s: string): number {
41+
// // 12
42+
// // dp 001
43+
// // 211
44+
45+
// // 226
46+
// // dp 0001
47+
// // 3211
48+
49+
// const dp = Array.from({ length: s.length + 1 }, (el) => 0);
50+
// dp[dp.length - 1] = 1;
51+
52+
// for (let start = s.length - 1; start >= 0; start--) {
53+
// if (s[start] === "0") {
54+
// dp[start] = 0;
55+
// } else if (
56+
// start + 1 < s.length &&
57+
// parseInt(s.substring(start, start + 2)) < 27
58+
// ) {
59+
// dp[start] = dp[start + 1] + dp[start + 2];
60+
// } else {
61+
// dp[start] = dp[start + 1];
62+
// }
63+
// }
64+
65+
// return dp[0];
66+
// }
67+
68+
69+
// Approach 2
70+
// ✅ Time Complexity: O(2^n) -> O(n)
71+
// Space Complexity: O(n)
72+
73+
// function numDecodings(s: string): number {
74+
// const memo = new Map<number, number>();
75+
// memo.set(s.length, 1);
76+
77+
// const dfs = (start: number) => {
78+
// if (memo.has(start)) return memo.get(start);
79+
// if (s[start] === "0") {
80+
// memo.set(start, 0);
81+
// } else if (
82+
// start + 1 < s.length &&
83+
// parseInt(s.substring(start, start + 2)) < 27
84+
// ) {
85+
// memo.set(start, dfs(start + 1)! + dfs(start + 2)!);
86+
// } else {
87+
// memo.set(start, dfs(start + 1)!);
88+
// }
89+
// return memo.get(start);
90+
// };
91+
// return dfs(0)!;
92+
// }
93+
94+
95+
// Approach 1
96+
// ❌ Time Limit Exceeded!
97+
// Time Complexity: O(2^n), where n = s.length
98+
// Space Compexity: O(n), due to recursive call stack
99+
// function numDecodings(s: string): number {
100+
// const dfs = (start: number) => {
101+
// if (start === s.length) {
102+
// return 1;
103+
// }
104+
105+
// if (s[start] === "0") {
106+
// return 0;
107+
// }
108+
109+
// if (start + 1 < s.length && parseInt(s.substring(start, start + 2)) < 27) {
110+
// return dfs(start + 1) + dfs(start + 2);
111+
// } else {
112+
// return dfs(start + 1);
113+
// }
114+
// };
115+
116+
// return dfs(0);
117+
// }

maximum-subarray/Jeehay28.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Approach 1:
2+
// Time Complexity: O(n)
3+
// Space Complexity: O(1)
4+
5+
function maxSubArray(nums: number[]): number {
6+
let currentSum = nums[0];
7+
let maxSum = nums[0];
8+
9+
for (let i = 1; i < nums.length; i++) {
10+
currentSum = Math.max(nums[i], currentSum + nums[i]);
11+
maxSum = Math.max(currentSum, maxSum);
12+
}
13+
14+
return maxSum;
15+
}
16+

number-of-1-bits/Jeehay28.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Approach 2
2+
// 🗓️ 2025-04-15
3+
// ⏳ Time Complexity: O(log n)
4+
// 💾 Space Complexity: O(1)
5+
6+
function hammingWeight(n: number): number {
7+
// n(이진수) & 1 -> 1: 이진수 n의 마지막 비트가 1인 경우에만 1 반환
8+
// n(이진수) >> 1: 마지막 비트 제거
9+
// 🔍 In binary numbers:
10+
// Decimal: 11
11+
// Binary: 1 0 1 1
12+
// ↑ ↑
13+
// MSB LSB
14+
// (Most Sig.) (Least Sig.)
15+
// n & 1: only checks the least significant bit (LSB), if the LSB is 1, the result is 1.
16+
// n >>= 1: Each bit is moved one place to the right.
17+
18+
let count = 0;
19+
20+
while (n) {
21+
count += n & 1; // add 1 if the least significant bit of n is 1
22+
n >>= 1; // The LSB is removed (dropped).
23+
}
24+
25+
return count;
26+
}
27+
28+
29+
// Approach 1
30+
// 🗓️ 2025-04-15
31+
// ⏳ Time Complexity: O(log n)
32+
// 💾 Space Complexity: O(1)
33+
34+
// function hammingWeight(n: number): number {
35+
// // input: a positive number n
36+
// // output: the number of set bits in binary representation
37+
// // set bits: a bit in the binary representaton of a number that has a value of 1
38+
// // 11 -> 1011 -> 3
39+
40+
// let cnt = 0;
41+
// while (n > 0) {
42+
// if (n % 2 === 1) {
43+
// cnt += 1;
44+
// }
45+
// n = Math.floor(n / 2);
46+
// }
47+
48+
// return cnt;
49+
// }
50+

valid-palindrome/Jeehay28.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Approach 2
2+
// 🗓️ 2025-04-14
3+
// ⏳ Time Complexity: O(n)
4+
// 💾 Space Complexity: O(1)
5+
6+
function isPalindrome(s: string): boolean {
7+
let low = 0, high = s.length - 1;
8+
const reg = /[0-9a-zA-Z]/;
9+
10+
while (low < high) {
11+
while (low < high && !reg.test(s[low])) {
12+
low += 1;
13+
}
14+
15+
while (low < high && !reg.test(s[high])) {
16+
high -= 1;
17+
}
18+
19+
if (s[low].toLowerCase() !== s[high].toLowerCase()) {
20+
return false;
21+
}
22+
low += 1;
23+
high -= 1;
24+
}
25+
26+
return true;
27+
}
28+
29+
30+
// Approach 1
31+
// 🗓️ 2025-04-14
32+
// ⏳ Time Complexity: O(n)
33+
// 💾 Space Complexity: O(n)
34+
35+
// function isPalindrome(s: string): boolean {
36+
// // cover all uppercase letters into lowercasse letters
37+
// // remove all non-alphanumeric characters (letters and numbers)
38+
// // it reads the same forward and backward
39+
40+
// const cleaned = s.toLowerCase().match(/[0-9a-z]/g);
41+
42+
// // Converting to lowercase (toLowerCase()): O(n), where n is the length of the string
43+
// // Matching with regex (match(/[0-9a-z]/g)): O(n), where n is the length of the string, as the regex engine needs to check each character in the string
44+
// // join("") operation: O(m), where m is the length of the cleaned array.
45+
// // reverse() operation: O(m), where m is the length of the cleaned array.
46+
// // Comparison (s_forward === s_backward): O(n) because it checks each character one by one
47+
48+
// if (cleaned !== null) {
49+
// const s_forward = cleaned.join("");
50+
// const s_backward = cleaned.reverse().join("");
51+
// return s_forward === s_backward;
52+
// } else {
53+
// return true;
54+
// }
55+
// }

0 commit comments

Comments
 (0)