Skip to content

Commit 5714288

Browse files
authored
Merge pull request DaleStudy#960 from Jeehay28/main
[Jeehay28] WEEK 08
2 parents 2496829 + 7bc13f3 commit 5714288

File tree

5 files changed

+286
-0
lines changed

5 files changed

+286
-0
lines changed

clone-graph/Jeehay28.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* // Definition for a _Node.
3+
* function _Node(val, neighbors) {
4+
* this.val = val === undefined ? 0 : val;
5+
* this.neighbors = neighbors === undefined ? [] : neighbors;
6+
* };
7+
*/
8+
9+
/**
10+
* @param {_Node} node
11+
* @return {_Node}
12+
*/
13+
14+
// BFS approach
15+
// Time Complexity: O(N + E), where N is the number of nodes and E is the number of edges.
16+
// Space Complexity: O(N), due to the clones map and additional storage (queue for BFS, recursion stack for DFS).
17+
18+
var cloneGraph = function (node) {
19+
if (!node) {
20+
return null;
21+
}
22+
let clone = new Node(node.val);
23+
let clones = new Map();
24+
clones.set(node, clone);
25+
let queue = [node];
26+
while (queue.length > 0) {
27+
node = queue.shift();
28+
for (const neighbor of node.neighbors) {
29+
if (!clones.get(neighbor)) {
30+
const temp = new Node(neighbor.val);
31+
clones.set(neighbor, temp);
32+
queue.push(neighbor);
33+
}
34+
clones.get(node).neighbors.push(clones.get(neighbor));
35+
}
36+
}
37+
38+
return clone;
39+
};
40+
41+
// DFS approach
42+
// Time Complexity: O(N + E), where N is the number of nodes and E is the number of edges.
43+
// Space Complexity: O(N), due to the clones map and the recursion stack.
44+
45+
var cloneGraph = function (node) {
46+
if (!node) {
47+
return null;
48+
}
49+
50+
let clones = new Map();
51+
52+
const dfs = (node) => {
53+
if (clones.has(node)) {
54+
return clones.get(node);
55+
}
56+
let clone = new Node(node.val);
57+
clones.set(node, clone);
58+
59+
for (neighbor of node.neighbors) {
60+
clone.neighbors.push(dfs(neighbor));
61+
}
62+
63+
return clone;
64+
};
65+
66+
return dfs(node);
67+
};
68+
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* @param {string} text1
3+
* @param {string} text2
4+
* @return {number}
5+
*/
6+
7+
// 🤔
8+
// Both memoization (top-down) and dynamic programming (bottom-up) have the same time and space complexity of O(m * n).
9+
// The difference lies in their implementation:
10+
// - Memoization uses recursion with a cache to avoid redundant calculations but may incur overhead from recursive calls and stack space.
11+
// - Dynamic Programming iteratively builds the solution, avoiding recursion overhead and sometimes offering better performance.
12+
// DP is often preferred when recursion depth or function call overhead is a concern, while memoization can be more intuitive for certain problems.
13+
14+
// 😊 memoization approach
15+
// Time Complexity: O(m * n), where m is the length of text1, and n is the length of text2
16+
// Space Complexity: O(m * n)
17+
// Top-down approach with recursion.
18+
// Use a cache (or memoization) to store intermediate results.
19+
20+
var longestCommonSubsequence = function (text1, text2) {
21+
const memo = new Map();
22+
23+
const dfs = (i, j) => {
24+
const key = `${i},${j}`; // Convert (i, j) into a unique string key
25+
if (memo.has(key)) {
26+
return memo.get(key);
27+
}
28+
29+
if (i === text1.length || j === text2.length) {
30+
memo.set(key, 0);
31+
} else if (text1[i] === text2[j]) {
32+
memo.set(key, 1 + dfs(i + 1, j + 1));
33+
} else {
34+
memo.set(key, Math.max(dfs(i + 1, j), dfs(i, j + 1)));
35+
}
36+
37+
return memo.get(key);
38+
};
39+
return dfs(0, 0);
40+
};
41+
42+
// 😊 bottom-up dynamic programming approach
43+
// Time Complexity: O(m * n), where m is the length of text1, and n is the length of text2
44+
// Space Complexity: O(m * n)
45+
46+
// text1 = "abcde"
47+
// text2 = "ace"
48+
49+
// "" a c e
50+
// "" 0 0 0 0
51+
// a 0 1 1 1
52+
// b 0 1 1 1
53+
// c 0 1 2 2
54+
// d 0 1 2 2
55+
// e 0 1 2 3
56+
57+
58+
// var longestCommonSubsequence = function (text1, text2) {
59+
// const dp = new Array(text1.length + 1)
60+
// .fill(0)
61+
// .map(() => new Array(text2.length + 1).fill(0));
62+
63+
// for (let i = 1; i <= text1.length; i++) {
64+
// for (let j = 1; j <= text2.length; j++) {
65+
// if (text1[i - 1] === text2[j - 1]) {
66+
// dp[i][j] = dp[i - 1][j - 1] + 1;
67+
// } else {
68+
// dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
69+
// }
70+
// }
71+
// }
72+
73+
// return dp[text1.length][text2.length];
74+
// };
75+
76+
77+
// 😱 Time Limit Exceeded!
78+
// Brute-force Recursion
79+
// Time Complexity: O(2^(m+n)) (Exponential)
80+
// Space Complexity: O(m + n) (Recursive Stack)
81+
82+
// var longestCommonSubsequence = function (text1, text2) {
83+
// const dfs = (i, j) => {
84+
// if (i === text1.length || j === text2.length) {
85+
// return 0;
86+
// }
87+
// if (text1[i] === text2[j]) {
88+
// return 1 + dfs(i + 1, j + 1);
89+
// }
90+
// return Math.max(dfs(i + 1, j), dfs(i, j + 1));
91+
// };
92+
// return dfs(0, 0);
93+
// };
94+
95+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @param {string} s
3+
* @param {number} k
4+
* @return {number}
5+
*/
6+
7+
// sliding window technique
8+
// Time complexity: O(n), where n is the length of the string. Both the start and end pointers traverse the string at most once.
9+
// Space Complexity: O(1), as we only need a fixed amount of extra space for the character frequency map and some variables.
10+
var characterReplacement = function (s, k) {
11+
let longest = 0;
12+
let maxCount = 0;
13+
const charCount = {};
14+
let start = 0;
15+
16+
for (let end = 0; end < s.length; end++) {
17+
const char = s[end];
18+
charCount[char] = (charCount[char] || 0) + 1;
19+
maxCount = Math.max(charCount[char], maxCount);
20+
21+
while (end - start + 1 - maxCount > k) {
22+
const temp = s[start];
23+
charCount[temp] -= 1;
24+
start += 1;
25+
}
26+
27+
longest = Math.max(longest, end - start + 1);
28+
}
29+
30+
return longest;
31+
};
32+

number-of-1-bits/Jeehay28.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// 💪 Optimized Approach: Brian Kernighan's Algorithm
2+
// Brian Kernighan's algorithm is a very efficient way to count the number of set bits in a number.
3+
// It works by repeatedly turning off the rightmost set bit.
4+
5+
// Time Complexity: O(k), where k is the number of set bits (1s) in the binary representation of n.
6+
// - Binary representation of 5 : 101
7+
8+
// Space Complexity: O(1)
9+
10+
/**
11+
*
12+
* @param {number} n - The number whose set bits need to be counted.
13+
* @return {number} - The number of set bits (1s) in the binary representation of n.
14+
*/
15+
16+
var hammingWeight = function (n) {
17+
let cnt = 0;
18+
19+
while (n > 0) {
20+
cnt += 1;
21+
n = n & (n - 1); // removes the rightmost set bit (1) in the binary representation of n, and the other bits remain unchanged
22+
}
23+
return cnt;
24+
};
25+
26+
// 💪 Improved versiion
27+
// TC: O(log n)
28+
// SC: O(1)
29+
// var hammingWeight = function(n) {
30+
31+
// let cnt = 0;
32+
33+
// while(n > 0) {
34+
// cnt += n % 2;
35+
// n = Math.floor(n / 2)
36+
// }
37+
// return cnt;
38+
39+
// };
40+
41+
// 💪 My own approach
42+
// Time Complexity: O(log n)
43+
// Space Complexity: O(log n)
44+
45+
/**
46+
* Time Complexity: O(log n)
47+
* - The operation `n.toString(2)` converts the number into its binary representation, which takes O(log n) time, where 'n' is the input number.
48+
* - The `replaceAll("0", "")` operation goes through the binary string to remove all '0' characters, which is O(log n) as the binary string has a length of log(n).
49+
* - The `.length` operation to count the '1' characters is O(log n) as well.
50+
* - Overall, the time complexity is O(log n) since we are iterating over the binary string twice (once to convert and once to remove zeros).
51+
52+
* Space Complexity: O(log n)
53+
* - The binary representation of the number is stored as a string, which takes O(log n) space, where log(n) is the length of the binary string.
54+
* - Therefore, the space complexity is O(log n) because of the space used to store the binary string during the conversion process.
55+
*/
56+
57+
/**
58+
* @param {number} n
59+
* @return {number}
60+
*/
61+
62+
// var hammingWeight = function (n) {
63+
// let binary = n.toString(2).replaceAll("0", "").length;
64+
65+
// return binary;
66+
// };
67+
68+

sum-of-two-integers/Jeehay28.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @param {number} a
3+
* @param {number} b
4+
* @return {number}
5+
*/
6+
7+
// Time Complexity: O(log(max(a, b)))
8+
// Space Complexity: O(1)
9+
10+
var getSum = function (a, b) {
11+
// XOR (^): outputs true (or 1) if the inputs are different, and false (or 0) if the inputs are the same.
12+
// And (&): compares each bit of two numbers and returns 1 only if both bits are 1; otherwise, it returns 0.
13+
// left shitf (<<): moves the bits one position to the left, which is the same as multiplying by 2.
14+
15+
while (b !== 0) {
16+
let carry = (a & b) << 1;
17+
a = a ^ b;
18+
b = carry;
19+
}
20+
21+
return a;
22+
};
23+

0 commit comments

Comments
 (0)