Skip to content

Commit a39fb5d

Browse files
authored
Merge pull request #1347 from Jeehay28/main
[Jeehay28] WEEK 04 Solutions
2 parents e2b6419 + 1d138c0 commit a39fb5d

File tree

5 files changed

+323
-0
lines changed

5 files changed

+323
-0
lines changed

coin-change/Jeehay28.ts

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Approach 2: Dynamic Programming
2+
// // Time Complexity: O(amout * n), where n is the number of coins
3+
// // Space Complexity: O(amount)
4+
5+
function coinChange(coins: number[], amount: number): number {
6+
7+
// input: coins = [2, 3, 5], amount = 7
8+
9+
// initial state dp
10+
// 0: 0
11+
// 1: amount + 1 = 8
12+
// 2: 8
13+
// 3: 8
14+
// 4: 8
15+
// 5: 8
16+
// 6: 8
17+
// 7: 8
18+
19+
// using coin 2
20+
// 0: 0
21+
// 1: 8
22+
// 2: 8 -> 8 vs dp[2-2] + 1 = 1 -> 1
23+
// 3: 8 -> 8 vs dp[3-2] + 1 = 9 -> 8
24+
// 4: 8 -> 8 vs dp[4-2] + 1 = 2 -> 2
25+
// 5: 8 -> 8 vs dp[5-2] + 1 = 9 -> 8
26+
// 6: 8 -> 8 vs dp[6-2] + 1 = 3 -> 3
27+
// 7: 8 -> 8 vs dp[7-2] + 1 = 9 -> 8
28+
29+
const dp = Array.from({ length: amount + 1 }, () => amount + 1);
30+
dp[0] = 0
31+
32+
for (const coin of coins) {
33+
for (let currentTotal = coin; currentTotal <= amount; currentTotal++) {
34+
dp[currentTotal] = Math.min(dp[currentTotal - coin] + 1, dp[currentTotal])
35+
}
36+
}
37+
38+
return dp[amount] > amount ? -1 : dp[amount]
39+
};
40+
41+
42+
// // Approach 1: BFS Traversal
43+
// // Time Complexity: O(amout * n), where n is the number of coins
44+
// // Space Complexity: O(amount)
45+
46+
// function coinChange(coins: number[], amount: number): number {
47+
// // queue: [[number of coints, current total]]
48+
// let queue = [[0, 0]];
49+
// let visited = new Set();
50+
51+
// while (queue.length > 0) {
52+
// const [cnt, total] = queue.shift()!;
53+
54+
// if (total === amount) {
55+
// return cnt;
56+
// }
57+
58+
// if (visited.has(total)) {
59+
// continue;
60+
// }
61+
// visited.add(total);
62+
63+
// for (const coin of coins) {
64+
// if (total + coin <= amount) {
65+
// queue.push([cnt + 1, total + coin]);
66+
// }
67+
// }
68+
// }
69+
70+
// return -1;
71+
// }
72+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Approach 2: binary search
2+
// Time Complexity: ✅ O(log n)
3+
// Space Complexity: O(1)
4+
5+
function findMin(nums: number[]): number {
6+
7+
let left = 0
8+
let right = nums.length - 1
9+
10+
while(left < right) {
11+
12+
const mid = Math.floor((left + right) / 2)
13+
14+
if(nums[mid] > nums[right]) {
15+
// the min must be to the right of mid
16+
left = mid + 1
17+
} else {
18+
// the mins could be mid or to the left
19+
right = mid
20+
}
21+
}
22+
23+
return nums[left]
24+
};
25+
26+
27+
// Approach 1:
28+
// Time Complexity: ❌ O(n)
29+
// Space Complexity: O(1)
30+
31+
// function findMin(nums: number[]): number {
32+
// // input: an array of length n sorted in ascending order
33+
// // rotate: a[n-1], a[0], ..., a[n-2]
34+
// // time complexity allowed: O(log n)
35+
36+
// let first = nums[0];
37+
// let last = nums[nums.length - 1];
38+
// let cnt = 0;
39+
40+
// while (first > last) {
41+
// first = last;
42+
// cnt += 1;
43+
// last = nums[nums.length - 1 - cnt];
44+
// }
45+
46+
// return first;
47+
// }
48+
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
class TreeNode {
2+
val: number;
3+
left: TreeNode | null;
4+
right: TreeNode | null;
5+
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
6+
this.val = val === undefined ? 0 : val;
7+
this.left = left === undefined ? null : left;
8+
this.right = right === undefined ? null : right;
9+
}
10+
}
11+
12+
// Approach 3:
13+
// Time Complexity: O(n)
14+
// Space Complexity: O(n), due to the recursion stack
15+
16+
function maxDepth(root: TreeNode | null): number {
17+
if (!root) return 0;
18+
19+
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));
20+
}
21+
22+
// Approach 2:
23+
// Time Complexity: O(n)
24+
// Space Complexity: O(n)
25+
26+
// function maxDepth(root: TreeNode | null): number {
27+
// if (!root) return 0;
28+
29+
// let maxDepth = 0;
30+
// let stack: Array<[TreeNode, number]> = [[root, 1]];
31+
32+
// while (stack.length > 0) {
33+
// const item = stack.pop();
34+
35+
// if (!item) continue;
36+
37+
// const [node, depth] = item;
38+
39+
// maxDepth = Math.max(maxDepth, depth);
40+
41+
// if (node.left) {
42+
// stack.push([node.left, depth + 1]);
43+
// }
44+
45+
// if (node.right) {
46+
// stack.push([node.right, depth + 1]);
47+
// }
48+
// }
49+
50+
// return maxDepth;
51+
// }
52+
53+
54+
// Approach 1
55+
// Time Compleixty:O(n)
56+
// Space Complexity:O(n), due to the recursion stack
57+
58+
// function maxDepth(root: TreeNode | null): number {
59+
// let maxCnt = 0;
60+
61+
// const dfs = (node: TreeNode | null, cnt: number) => {
62+
// if (!node) {
63+
// maxCnt = Math.max(maxCnt, cnt);
64+
// return;
65+
// }
66+
67+
// dfs(node.left, cnt + 1);
68+
// dfs(node.right, cnt + 1);
69+
// };
70+
71+
// dfs(root, 0);
72+
73+
// return maxCnt;
74+
// }
75+

merge-two-sorted-lists/Jeehay28.ts

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Approach 2:
2+
// ✅ Time Complexity: O(n)
3+
// ✅ Space Complexity: O(1)
4+
5+
class ListNode {
6+
val: number;
7+
next: ListNode | null;
8+
constructor(val?: number, next?: ListNode | null) {
9+
this.val = val === undefined ? 0 : val;
10+
this.next = next === undefined ? null : next;
11+
}
12+
}
13+
14+
function mergeTwoLists(
15+
list1: ListNode | null,
16+
list2: ListNode | null
17+
): ListNode | null {
18+
let dummy = new ListNode(0);
19+
let current = dummy;
20+
21+
while (list1 && list2) {
22+
if (list1.val <= list2.val) {
23+
current.next = list1;
24+
list1 = list1.next;
25+
} else {
26+
current.next = list2;
27+
list2 = list2.next;
28+
}
29+
current = current.next;
30+
}
31+
32+
current.next = list1 || list2; // Attach whatever is left
33+
34+
return dummy.next;
35+
}
36+
37+
38+
// Approach 1: works, but not efficient for big inputs
39+
// Time Complexity: O(n log n)
40+
// Space Complexity: O(n)
41+
42+
// function mergeTwoLists(
43+
// list1: ListNode | null,
44+
// list2: ListNode | null
45+
// ): ListNode | null {
46+
// let stack: number[] = [];
47+
48+
// const dfs = (node: ListNode | null) => {
49+
// if (!node) {
50+
// return;
51+
// }
52+
53+
// stack.push(node.val);
54+
55+
// return dfs(node.next);
56+
// };
57+
58+
// dfs(list1);
59+
// dfs(list2);
60+
61+
// stack.sort((a, b) => a - b);
62+
63+
// if (stack.length === 0) {
64+
// return null;
65+
// }
66+
67+
// let merged = new ListNode();
68+
// let dummy = merged;
69+
70+
// for (let i = 0; i < stack.length; i++) {
71+
// dummy.val = stack[i];
72+
73+
// if (i !== stack.length - 1) {
74+
// dummy.next = new ListNode();
75+
// dummy = dummy.next;
76+
// } else {
77+
// dummy.next = null;
78+
// }
79+
// }
80+
81+
// return merged;
82+
// }

word-search/Jeehay28.ts

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Time Complexity: O(m * n * 4^L), where L is the length of the word
2+
// Space Complexity: O(L) due to he recursive call stack
3+
4+
function exist(board: string[][], word: string): boolean {
5+
// input: m * n grid of characters board, a string word
6+
// output: true if word exists in the grid
7+
8+
const dfs = (index: number, row: number, col: number) => {
9+
if (
10+
row < 0 ||
11+
row >= board.length ||
12+
col < 0 ||
13+
col >= board[0].length ||
14+
board[row][col] !== word[index]
15+
) {
16+
return false;
17+
}
18+
19+
if (index === word.length - 1) {
20+
return true;
21+
}
22+
23+
const visited = board[row][col];
24+
board[row][col] = "#";
25+
26+
const result =
27+
dfs(index + 1, row + 1, col) ||
28+
dfs(index + 1, row - 1, col) ||
29+
dfs(index + 1, row, col + 1) ||
30+
dfs(index + 1, row, col - 1);
31+
32+
board[row][col] = visited;
33+
34+
return result;
35+
};
36+
37+
for (let i = 0; i < board.length; i++) {
38+
for (let j = 0; j < board[0].length; j++) {
39+
if (dfs(0, i, j)) {
40+
return true;
41+
}
42+
}
43+
}
44+
45+
return false;
46+
}

0 commit comments

Comments
 (0)