From cc061c9c1e5b67bc94071af4aeb0109f0d6f7a3b Mon Sep 17 00:00:00 2001 From: Paik Date: Sat, 4 Jan 2025 09:48:44 +0900 Subject: [PATCH 1/8] feat: 121. Best Time to Buy and Sell Stock --- best-time-to-buy-and-sell-stock/gwbaik9717.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 best-time-to-buy-and-sell-stock/gwbaik9717.js diff --git a/best-time-to-buy-and-sell-stock/gwbaik9717.js b/best-time-to-buy-and-sell-stock/gwbaik9717.js new file mode 100644 index 000000000..a42e22825 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/gwbaik9717.js @@ -0,0 +1,18 @@ +// Time complexity: O(n) +// Space complexity: O(1) + +/** + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function (prices) { + let answer = 0; + let minValue = Number.MAX_SAFE_INTEGER; + + for (const price of prices) { + minValue = Math.min(minValue, price); + answer = Math.max(answer, price - minValue); + } + + return answer; +}; From 040d1c54c4a329a74f1a64ea9426c7b8e5897be0 Mon Sep 17 00:00:00 2001 From: Paik Date: Sat, 4 Jan 2025 10:15:28 +0900 Subject: [PATCH 2/8] feat: 49. Group Anagrams --- group-anagrams/gwbaik9717.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 group-anagrams/gwbaik9717.js diff --git a/group-anagrams/gwbaik9717.js b/group-anagrams/gwbaik9717.js new file mode 100644 index 000000000..6a54f7fcb --- /dev/null +++ b/group-anagrams/gwbaik9717.js @@ -0,0 +1,35 @@ +// n: length of strs, m: length of strs[i] +// Time complexity: O(nmlogm) +// Space complexity: O(n) + +/** + * @param {string[]} strs + * @return {string[][]} + */ +var groupAnagrams = function (strs) { + const answer = []; + const anagramDict = new Map(); + + const sortedStrs = strs.map((str) => { + const splitted = str.split(""); + splitted.sort(); + return splitted.join(""); + }); + + for (let i = 0; i < sortedStrs.length; i++) { + const sortedStr = sortedStrs[i]; + const originalStr = strs[i]; + + if (!anagramDict.has(sortedStr)) { + anagramDict.set(sortedStr, []); + } + + anagramDict.get(sortedStr).push(originalStr); + } + + for (const [_, value] of anagramDict) { + answer.push(value); + } + + return answer; +}; From 1e90ed072a446324cd071404dd0ae5d90299d661 Mon Sep 17 00:00:00 2001 From: Paik Date: Sat, 4 Jan 2025 10:45:47 +0900 Subject: [PATCH 3/8] refactor: 49. Group Anagrams --- group-anagrams/gwbaik9717.js | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/group-anagrams/gwbaik9717.js b/group-anagrams/gwbaik9717.js index 6a54f7fcb..6f812a09b 100644 --- a/group-anagrams/gwbaik9717.js +++ b/group-anagrams/gwbaik9717.js @@ -1,5 +1,5 @@ // n: length of strs, m: length of strs[i] -// Time complexity: O(nmlogm) +// Time complexity: O(nm) // Space complexity: O(n) /** @@ -10,21 +10,29 @@ var groupAnagrams = function (strs) { const answer = []; const anagramDict = new Map(); - const sortedStrs = strs.map((str) => { - const splitted = str.split(""); - splitted.sort(); - return splitted.join(""); - }); + const getKey = (str) => { + const counter = Array.from( + { length: "z".charCodeAt() - "a".charCodeAt() + 1 }, + () => 0 + ); - for (let i = 0; i < sortedStrs.length; i++) { - const sortedStr = sortedStrs[i]; - const originalStr = strs[i]; + for (const chr of str) { + const index = chr.charCodeAt() - "a".charCodeAt(); + counter[index]++; + } + + return counter.join("#"); + }; + + for (let i = 0; i < strs.length; i++) { + const str = strs[i]; + const key = getKey(str); - if (!anagramDict.has(sortedStr)) { - anagramDict.set(sortedStr, []); + if (!anagramDict.has(key)) { + anagramDict.set(key, []); } - anagramDict.get(sortedStr).push(originalStr); + anagramDict.get(key).push(str); } for (const [_, value] of anagramDict) { From 1ce40c1dc6890f699637790183485a7ce7426024 Mon Sep 17 00:00:00 2001 From: Paik Date: Mon, 6 Jan 2025 20:03:48 +0900 Subject: [PATCH 4/8] 139. Word Break --- word-break/gwbaik9717.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 word-break/gwbaik9717.js diff --git a/word-break/gwbaik9717.js b/word-break/gwbaik9717.js new file mode 100644 index 000000000..ca7754f75 --- /dev/null +++ b/word-break/gwbaik9717.js @@ -0,0 +1,25 @@ +// n: len(s), m: len(wordDict) +// Time complexity: O(n^2*m) +// Space complexity: O(n) + +/** + * @param {string} s + * @param {string[]} wordDict + * @return {boolean} + */ +var wordBreak = function (s, wordDict) { + const dp = Array.from({ length: s.length + 1 }, () => false); + dp[0] = true; + + for (let i = 1; i <= s.length; i++) { + for (const word of wordDict) { + const sliced = s.slice(i - word.length, i); + + if (word === sliced && !dp[i]) { + dp[i] = dp[i - word.length]; + } + } + } + + return dp.at(-1); +}; From a302c0f33f5ec3c5e29e491faeca4ec5d354d8a8 Mon Sep 17 00:00:00 2001 From: Paik Date: Tue, 7 Jan 2025 09:33:59 +0900 Subject: [PATCH 5/8] 208. Implement Trie (Prefix Tree) --- implement-trie-prefix-tree/gwbaik9717.js | 70 ++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 implement-trie-prefix-tree/gwbaik9717.js diff --git a/implement-trie-prefix-tree/gwbaik9717.js b/implement-trie-prefix-tree/gwbaik9717.js new file mode 100644 index 000000000..401669cb3 --- /dev/null +++ b/implement-trie-prefix-tree/gwbaik9717.js @@ -0,0 +1,70 @@ +var Node = function () { + this.children = new Map(); + this.isEnd = false; +}; + +var Trie = function () { + this.head = new Node(); +}; + +/** + * @param {string} word + * @return {void} + */ +Trie.prototype.insert = function (word) { + let current = this.head; + + for (const chr of word) { + if (!current.children.has(chr)) { + current.children.set(chr, new Node()); + } + + current = current.children.get(chr); + } + + current.isEnd = true; +}; + +/** + * @param {string} word + * @return {boolean} + */ +Trie.prototype.search = function (word) { + let current = this.head; + + for (const chr of word) { + if (!current.children.has(chr)) { + return false; + } + + current = current.children.get(chr); + } + + return current.isEnd; +}; + +/** + * @param {string} prefix + * @return {boolean} + */ +Trie.prototype.startsWith = function (prefix) { + let current = this.head; + + for (const chr of prefix) { + if (!current.children.has(chr)) { + return false; + } + + current = current.children.get(chr); + } + + return true; +}; + +/** + * Your Trie object will be instantiated and called as such: + * var obj = new Trie() + * obj.insert(word) + * var param_2 = obj.search(word) + * var param_3 = obj.startsWith(prefix) + */ From 8f6c82f0e77e5d90da2503e878df298e3ce1282d Mon Sep 17 00:00:00 2001 From: Paik Date: Thu, 9 Jan 2025 10:27:39 +0900 Subject: [PATCH 6/8] feat: 659.encode-and-decode-strings --- encode-and-decode-strings/gwbaik9717.js | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 encode-and-decode-strings/gwbaik9717.js diff --git a/encode-and-decode-strings/gwbaik9717.js b/encode-and-decode-strings/gwbaik9717.js new file mode 100644 index 000000000..68ddc950b --- /dev/null +++ b/encode-and-decode-strings/gwbaik9717.js @@ -0,0 +1,37 @@ +// n: len(str) +// Time complexity: O(n) +// Space complexity: O(1) +const encode = function (arr) { + let answer = ""; + + for (const word of arr) { + answer += `${word.length}${SEPERATOR}`; + } + + return answer; +}; + +// n: len(str) +// Time complexity: O(n) +// Space complexity: O(n) +const decode = function (str) { + const SEPERATOR = "|"; + const words = []; + + let i = 0; + let wordLength = ""; + + while (i < str.length) { + if (str[i] === SEPERATOR) { + words.push(str.slice(i + 1, i + 1 + Number(wordLength))); + i += Number(wordLength) + 1; + wordLength = ""; + continue; + } + + wordLength += str[i]; + i += 1; + } + + return words; +}; From e4aaeab1f3c5f5e1047237cfd4faf0897d7afd8e Mon Sep 17 00:00:00 2001 From: Paik Date: Fri, 10 Jan 2025 08:50:38 +0900 Subject: [PATCH 7/8] refactor: 49. Group Anagrams --- group-anagrams/gwbaik9717.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/group-anagrams/gwbaik9717.js b/group-anagrams/gwbaik9717.js index 6f812a09b..68633e595 100644 --- a/group-anagrams/gwbaik9717.js +++ b/group-anagrams/gwbaik9717.js @@ -11,13 +11,16 @@ var groupAnagrams = function (strs) { const anagramDict = new Map(); const getKey = (str) => { + const minCharCode = "a".charCodeAt(); + const maxCharCode = "z".charCodeAt(); + const counter = Array.from( - { length: "z".charCodeAt() - "a".charCodeAt() + 1 }, + { length: maxCharCode - minCharCode + 1 }, () => 0 ); for (const chr of str) { - const index = chr.charCodeAt() - "a".charCodeAt(); + const index = chr.charCodeAt() - minCharCode; counter[index]++; } From 2d16acd183dc593ac68c6bd0cfdd1dbd8b13ad77 Mon Sep 17 00:00:00 2001 From: Paik Date: Fri, 10 Jan 2025 09:03:58 +0900 Subject: [PATCH 8/8] refactor: 208. Implement Trie (Prefix Tree) --- implement-trie-prefix-tree/gwbaik9717.js | 39 +++++++++++++++--------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/implement-trie-prefix-tree/gwbaik9717.js b/implement-trie-prefix-tree/gwbaik9717.js index 401669cb3..5d47e8fb6 100644 --- a/implement-trie-prefix-tree/gwbaik9717.js +++ b/implement-trie-prefix-tree/gwbaik9717.js @@ -7,6 +7,23 @@ var Trie = function () { this.head = new Node(); }; +/** + * @param {string} str + * @return {TrieNode | null} + */ +Trie.prototype._traverse = function (str) { + let current = this.head; + + for (const chr of str) { + if (!current.children.has(chr)) { + return null; + } + current = current.children.get(chr); + } + + return current; +}; + /** * @param {string} word * @return {void} @@ -30,17 +47,13 @@ Trie.prototype.insert = function (word) { * @return {boolean} */ Trie.prototype.search = function (word) { - let current = this.head; - - for (const chr of word) { - if (!current.children.has(chr)) { - return false; - } + const node = this._traverse(word); - current = current.children.get(chr); + if (!node) { + return false; } - return current.isEnd; + return node.isEnd; }; /** @@ -48,14 +61,10 @@ Trie.prototype.search = function (word) { * @return {boolean} */ Trie.prototype.startsWith = function (prefix) { - let current = this.head; + const node = this._traverse(prefix); - for (const chr of prefix) { - if (!current.children.has(chr)) { - return false; - } - - current = current.children.get(chr); + if (!node) { + return false; } return true;