Skip to content

Commit 132b69e

Browse files
authored
Merge pull request #891 from Jeehay28/main
[Jeehay28] WEEK 06
2 parents cc7d2dd + ec041f9 commit 132b69e

File tree

5 files changed

+343
-0
lines changed

5 files changed

+343
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @param {number[]} height
3+
* @return {number}
4+
*/
5+
6+
// Time Complexity: O(n)
7+
// Space Complexity: O(1)
8+
var maxArea = function (height) {
9+
let start = 0;
10+
let end = height.length - 1;
11+
let maxArea = 0;
12+
13+
while (start < end) {
14+
const area = (end - start) * Math.min(height[start], height[end]);
15+
maxArea = Math.max(area, maxArea);
16+
17+
// The shorter height limits the area.
18+
// By moving the pointer associated with the shorter height,
19+
// the algorithm maximizes the chance of finding a taller line that can increase the area.
20+
// This is the essence of the two-pointer strategy for the container problem.
21+
if (height[start] < height[end]) {
22+
start += 1;
23+
} else {
24+
end -= 1;
25+
}
26+
}
27+
return maxArea;
28+
};
29+
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/**
2+
* ==================== Complexity Summary ====================
3+
* | Operation | Time Complexity | Space Complexity |
4+
* |------------|------------------------|--------------------|
5+
* | addWord | O(n) | O(n) |
6+
* | search | O(n) (no '.') | O(n) |
7+
* | | O(k^n) (with '.') | O(n) |
8+
* ============================================================
9+
*
10+
* Notes:
11+
* - n: Length of the word being added/searched.
12+
* - k: Average branching factor (number of children per node).
13+
* - Worst-case time complexity for `search` with '.' can grow exponentially
14+
* when many wildcards are present in the word.
15+
*/
16+
17+
var WordDictionary = function () {
18+
this.root = { $: false };
19+
};
20+
21+
/**
22+
* @param {string} word
23+
* @return {void}
24+
*/
25+
WordDictionary.prototype.addWord = function (word) {
26+
let node = this.root;
27+
28+
for (char of word) {
29+
if (!node[char]) {
30+
node[char] = { $: false };
31+
}
32+
node = node[char];
33+
}
34+
35+
node["$"] = true;
36+
};
37+
38+
/**
39+
* @param {string} word
40+
* @return {boolean}
41+
*/
42+
WordDictionary.prototype.search = function (word) {
43+
const dfs = (node, index) => {
44+
// Base case: If we've reached the end of the word
45+
if (index === word.length) {
46+
return node["$"] === true;
47+
}
48+
49+
const char = word[index];
50+
51+
// If the character is not a wildcard
52+
if (char !== ".") {
53+
if (node[char]) {
54+
return dfs(node[char], index + 1); // Continue DFS
55+
} else {
56+
return false; // Character not found
57+
}
58+
}
59+
60+
// If the character is a wildcard
61+
for (const key of Object.keys(node).filter((key) => key !== "$")) {
62+
if (dfs(node[key], index + 1)) {
63+
return true; // Return true if any child path matches
64+
}
65+
// Why we need to check if the recursive call to dfs returns true or false:
66+
// 1) Early termination of recursion when a match is found:
67+
// - Once we find a valid match, there's no need to explore other branches.
68+
// 2) Proper propagation of the result back up the recursion stack:
69+
// - A valid match found in a deeper level of recursion needs to return true
70+
// all the way back to the initial search call to indicate success.
71+
}
72+
73+
return false; // No paths matched for the wildcard
74+
};
75+
76+
return dfs(this.root, 0); // Start DFS from the root node
77+
};
78+
79+
/**
80+
* Your WordDictionary object will be instantiated and called as such:
81+
* var obj = new WordDictionary()
82+
* obj.addWord(word)
83+
* var param_2 = obj.search(word)
84+
*/
85+
86+
// ***** second trial *****
87+
// var WordDictionary = function () {
88+
// this.root = { $: true };
89+
// };
90+
91+
// /**
92+
// * @param {string} word
93+
// * @return {void}
94+
// */
95+
// WordDictionary.prototype.addWord = function (word) {
96+
// const dfs = (node, index) => {
97+
// // exit
98+
// if (index === word.length) {
99+
// node["$"] = true;
100+
// return;
101+
// }
102+
103+
// // add .
104+
// if (!node["."]) {
105+
// node["."] = { $: false };
106+
// }
107+
// dfs(node["."], index + 1);
108+
109+
// // add each character
110+
// const temp = word[index];
111+
112+
// if (!node[temp]) {
113+
// node[temp] = { $: false };
114+
// }
115+
// dfs(node[temp], index + 1);
116+
// };
117+
118+
// dfs(this.root, 0);
119+
// };
120+
121+
// /**
122+
// * @param {string} word
123+
// * @return {boolean}
124+
// */
125+
// WordDictionary.prototype.search = function (word) {
126+
// let node = this.root;
127+
128+
// for (char of word) {
129+
// if (!node[char]) {
130+
// return false;
131+
// }
132+
// node = node[char];
133+
// }
134+
135+
// return node["$"];
136+
// };
137+
138+
/**
139+
* Your WordDictionary object will be instantiated and called as such:
140+
* var obj = new WordDictionary()
141+
* obj.addWord(word)
142+
* var param_2 = obj.search(word)
143+
*/
144+
145+
// ***** first trial *****
146+
// var WordDictionary = function () {
147+
// this.root = new Set();
148+
// };
149+
150+
// /**
151+
// * @param {string} word
152+
// * @return {void}
153+
// */
154+
// WordDictionary.prototype.addWord = function (word) {
155+
// this.root.add(word);
156+
// };
157+
158+
// /**
159+
// * @param {string} word
160+
// * @return {boolean}
161+
// */
162+
// WordDictionary.prototype.search = function (word) {
163+
// if (this.root.size === 0) {
164+
// return false;
165+
// } else {
166+
// for (dict of this.root) {
167+
// if (dict.length === word.length) {
168+
// const found = word
169+
// .split("")
170+
// .every((str, index) => str === "." || dict[index] === str);
171+
// if (found) {
172+
// return true;
173+
// }
174+
// } else {
175+
// continue;
176+
// }
177+
// }
178+
// return false;
179+
// }
180+
// };
181+
182+
/**
183+
* Your WordDictionary object will be instantiated and called as such:
184+
* var obj = new WordDictionary()
185+
* obj.addWord(word)
186+
* var param_2 = obj.search(word)
187+
*/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number}
4+
*/
5+
6+
// Time Complexity: O(n^)
7+
// Space Complexity: O(n)
8+
var lengthOfLIS = function (nums) {
9+
if (nums.length === 0) {
10+
return 0;
11+
}
12+
13+
let dp = new Array(nums.length).fill(1); // dp[i] will be the length of LIS ending at i
14+
15+
for (let i = 1; i < nums.length; i++) {
16+
for (let j = 0; j < i; j++) {
17+
if (nums[i] > nums[j]) {
18+
// Strictly increasing condition
19+
dp[i] = Math.max(dp[i], dp[j] + 1);
20+
}
21+
}
22+
}
23+
24+
return Math.max(...dp); // The length of the longest subsequence
25+
};
26+

spiral-matrix/Jeehay28.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Time Complexity: O(m * n), where m is the number of rows and n is the number of columns in the matrix,
2+
// because every element is processed once.
3+
4+
// Space Complexity: O(m * n), where m is the number of rows and n is the number of columns in the matrix,
5+
// because we store all matrix elements in the result array.
6+
7+
/**
8+
* @param {number[][]} matrix
9+
* @return {number[]}
10+
*/
11+
var spiralOrder = function (matrix) {
12+
13+
let topRow = 0;
14+
let bottomRow = matrix.length - 1;
15+
let leftCol = 0;
16+
let rightCol = matrix[0].length - 1;
17+
let result = [];
18+
19+
while (topRow <= bottomRow && leftCol <= rightCol) {
20+
// move to the right
21+
for (let col = leftCol; col <= rightCol; col++) {
22+
result.push(matrix[topRow][col]);
23+
}
24+
25+
topRow += 1;
26+
27+
if (topRow > bottomRow) {
28+
break;
29+
}
30+
31+
// move down
32+
for (let row = topRow; row <= bottomRow; row++) {
33+
result.push(matrix[row][rightCol]);
34+
}
35+
36+
rightCol -= 1;
37+
38+
if (leftCol > rightCol) {
39+
break;
40+
}
41+
42+
// move to the left
43+
for (let col = rightCol; col >= leftCol; col--) {
44+
result.push(matrix[bottomRow][col]);
45+
}
46+
47+
bottomRow -= 1;
48+
if (topRow > bottomRow) {
49+
break;
50+
}
51+
52+
// move up
53+
for (let row = bottomRow; row >= topRow; row--) {
54+
result.push(matrix[row][leftCol]);
55+
}
56+
57+
leftCol += 1;
58+
59+
if (leftCol > rightCol) {
60+
break;
61+
}
62+
}
63+
64+
return result;
65+
};
66+

valid-parentheses/Jeehay28.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @param {string} s
3+
* @return {boolean}
4+
*/
5+
6+
// Time Complexity: O(n)
7+
// Space Complexity: O(n)
8+
var isValid = function (s) {
9+
const obj = {
10+
"(" : ")",
11+
"{" : "}",
12+
"[" : "]",
13+
};
14+
15+
let stack = [];
16+
17+
for (any of s) {
18+
// open bracket
19+
if (obj[any]) {
20+
stack.push(any);
21+
} else {
22+
// close bracket
23+
if (stack.length === 0) {
24+
return false;
25+
} else if (obj[stack[stack.length - 1]] !== any) {
26+
return false;
27+
} else {
28+
stack.pop();
29+
}
30+
}
31+
}
32+
return stack.length === 0 ? true : false;
33+
};
34+
35+

0 commit comments

Comments
 (0)