From 2b072ce4557323fcb060b5b4ebe0fa23a884e5bd Mon Sep 17 00:00:00 2001 From: tolluset Date: Sun, 8 Sep 2024 23:54:04 +0900 Subject: [PATCH 1/8] solve: best time to by and sell stock --- best-time-to-buy-and-sell-stock/tolluset.ts | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 best-time-to-buy-and-sell-stock/tolluset.ts diff --git a/best-time-to-buy-and-sell-stock/tolluset.ts b/best-time-to-buy-and-sell-stock/tolluset.ts new file mode 100644 index 000000000..3ef811a70 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/tolluset.ts @@ -0,0 +1,31 @@ +/* + * TC: O(n^2) + * SC: O(1) + * */ +function maxProfit(prices: number[]): number { + const n = prices.length; + + let max = 0; + + for (let i = 0; i < n; i++) { + let currentMax = 0; + + for (let j = i + 1; j < n; j++) { + if (prices[i] <= prices[j]) { + const profit = prices[j] - prices[i]; + + currentMax = Math.max(currentMax, profit); + } + } + + max = Math.max(max, currentMax); + } + + return max; +} + +const tc1 = maxProfit([7, 1, 5, 3, 6, 4]); +console.info("🚀 : tolluset.ts:5: tc1=", tc1); // 5 + +const tc2 = maxProfit([7, 6, 4, 3, 1]); +console.info("🚀 : tolluset.ts:8: tc2=", tc2); // 0 From c7fb410f5c747b0b7f7a49f43607cd1c83246b18 Mon Sep 17 00:00:00 2001 From: tolluset Date: Mon, 9 Sep 2024 00:18:23 +0900 Subject: [PATCH 2/8] solve: best time to by and sell stock 2 --- best-time-to-buy-and-sell-stock/tolluset.ts | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/best-time-to-buy-and-sell-stock/tolluset.ts b/best-time-to-buy-and-sell-stock/tolluset.ts index 3ef811a70..1ec857d67 100644 --- a/best-time-to-buy-and-sell-stock/tolluset.ts +++ b/best-time-to-buy-and-sell-stock/tolluset.ts @@ -1,4 +1,36 @@ /* + * TC: O(n) + * SC: O(1) + * */ +function maxProfitV2(prices: number[]): number { + const n = prices.length; + + let min = Infinity, + max = 0; + + for (let i = 0; i < n; i++) { + if (prices[i] < min) { + min = prices[i]; + continue; + } + + if (prices[i] - min > max) { + max = prices[i] - min; + continue; + } + } + + return max; +} + +const tc1V2 = maxProfitV2([7, 1, 5, 3, 6, 4]); +console.info("🚀 : tolluset.ts:27: tc1V2=", tc1V2); // 5 + +const tc2V2 = maxProfitV2([7, 6, 4, 3, 1]); +console.info("🚀 : tolluset.ts:30: tc2V2=", tc2V2); // 0 + +/* + * @FAILED: Time Limit Exceeded * TC: O(n^2) * SC: O(1) * */ From 5d9fc46a5bcfdf688e149d8bf8d0a44df008911f Mon Sep 17 00:00:00 2001 From: tolluset Date: Sat, 14 Sep 2024 14:07:46 +0900 Subject: [PATCH 3/8] solve: group anagrams --- group-anagrams/tolluset.ts | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 group-anagrams/tolluset.ts diff --git a/group-anagrams/tolluset.ts b/group-anagrams/tolluset.ts new file mode 100644 index 000000000..27966a537 --- /dev/null +++ b/group-anagrams/tolluset.ts @@ -0,0 +1,72 @@ +/* n: strs.length, m: strs.mean + * TC: O(n * m * logm) + * SC: O(n * m) + * */ +function groupAnagramsV2(strs: string[]): string[][] { + const map: { [key: string]: string[] } = {}; + + const strSort = (str: string) => str.split("").sort().join(""); + + for (const str of strs) { + const sortedStr = strSort(str); + + if (map[sortedStr]) { + map[sortedStr].push(str); + } else { + map[sortedStr] = [str]; + } + } + + return Object.values(map); +} + +const tc1V2 = groupAnagramsV2(["eat", "tea", "tan", "ate", "nat", "bat"]); // [["bat"],["nat","tan"],["ate","eat","tea"]] +console.info("🚀 : tolluset.ts:19: tc1V2=", tc1V2); + +/** + * @FAILED - Time Limit Exceeded + * TC: O(n^2) + * SC: O(n) + */ +function groupAnagrams(strs: string[]): string[][] { + const n = strs.length; + + const res: string[][] = []; + + const strSort = (str: string) => str.split("").sort().join(""); + + for (let i = 0; i < n; i++) { + const bucket: string[] = []; + const cur = strs[i]; + + if (cur === "#") { + continue; + } + + bucket.push(cur); + + const sortedCur = strSort(cur); + + for (let j = i + 1; j < n; j++) { + const tmpSortedStr = strSort(strs[j]); + + if (tmpSortedStr === "#") { + continue; + } + + if (sortedCur === tmpSortedStr) { + bucket.push(strs[j]); + strs[j] = "#"; + } + } + + strs[i] = "#"; + + res.push(bucket); + } + + return res; +} + +const tc1 = groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]); // [["bat"],["nat","tan"],["ate","eat","tea"]] +console.info("🚀 : tolluset.ts:7: tc1=", tc1); From d87dac38c450f68bace0948476e7df022cbb7e8f Mon Sep 17 00:00:00 2001 From: tolluset Date: Sat, 14 Sep 2024 14:43:53 +0900 Subject: [PATCH 4/8] solve: 3 sum --- 3sum/tolluset.ts | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 3sum/tolluset.ts diff --git a/3sum/tolluset.ts b/3sum/tolluset.ts new file mode 100644 index 000000000..906d2e30b --- /dev/null +++ b/3sum/tolluset.ts @@ -0,0 +1,56 @@ +/* + * TC: O(n^2) + * SC: O(n) + * */ +function threeSum(nums: number[]): number[][] { + const n = nums.length; + const res: number[][] = []; + + nums.sort((a, b) => a - b); + + for (let i = 0; i < n - 2; i++) { + if (i > 0 && nums[i] === nums[i - 1]) { + continue; + } + + let left = i + 1, + right = n - 1; + + while (left < right) { + const sum = nums[i] + nums[left] + nums[right]; + + if (sum === 0) { + res.push([nums[i], nums[left], nums[right]]); + + while (nums[left] === nums[left + 1]) { + left++; + } + + while (nums[right] === nums[right - 1]) { + right++; + } + + left++; + right--; + + continue; + } + + if (sum < 0) { + left++; + + continue; + } + + right--; + } + } + + return res; +} + +const tc1 = threeSum([-1, 0, 1, 2, -1, -4]); // [[-1,-1,2],[-1,0,1]] +console.info("🚀 : tolluset.ts:39: tc1=", tc1); + +const tc2 = threeSum([0, 0, 0]); // [[0,0,0]] +console.info("🚀 : tolluset.ts:42: tc2=", tc2); From 808247fb8027beab88059ae545d415a5a083663c Mon Sep 17 00:00:00 2001 From: tolluset Date: Sat, 14 Sep 2024 14:54:52 +0900 Subject: [PATCH 5/8] refactor: use map --- group-anagrams/tolluset.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/group-anagrams/tolluset.ts b/group-anagrams/tolluset.ts index 27966a537..2efb88632 100644 --- a/group-anagrams/tolluset.ts +++ b/group-anagrams/tolluset.ts @@ -3,21 +3,21 @@ * SC: O(n * m) * */ function groupAnagramsV2(strs: string[]): string[][] { - const map: { [key: string]: string[] } = {}; + const map = new Map(); const strSort = (str: string) => str.split("").sort().join(""); for (const str of strs) { const sortedStr = strSort(str); - if (map[sortedStr]) { - map[sortedStr].push(str); + if (map.has(sortedStr)) { + map.get(sortedStr)!.push(str); } else { - map[sortedStr] = [str]; + map.set(sortedStr, [str]); } } - return Object.values(map); + return Array.from(map.values()); } const tc1V2 = groupAnagramsV2(["eat", "tea", "tan", "ate", "nat", "bat"]); // [["bat"],["nat","tan"],["ate","eat","tea"]] From 3ae37aa4b6aeb326f6f5b106a7a2adb0bf22a6a7 Mon Sep 17 00:00:00 2001 From: tolluset Date: Sat, 14 Sep 2024 15:14:14 +0900 Subject: [PATCH 6/8] solve: implement trie prefix tree --- implement-trie-prefix-tree/tolluset.ts | 97 ++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 implement-trie-prefix-tree/tolluset.ts diff --git a/implement-trie-prefix-tree/tolluset.ts b/implement-trie-prefix-tree/tolluset.ts new file mode 100644 index 000000000..d49eaca48 --- /dev/null +++ b/implement-trie-prefix-tree/tolluset.ts @@ -0,0 +1,97 @@ +class TrieNode { + public children: Map; + public isEnd: boolean; + + constructor() { + this.children = new Map(); + this.isEnd = false; + } +} + +class Trie { + private root: TrieNode; + + constructor() { + this.root = new TrieNode(); + } + + /** + * TC: O(n) + * SC: O(n) + * */ + insert(word: string): void { + let node = this.root; + + for (const char of word) { + if (!node.children.has(char)) { + node.children.set(char, new TrieNode()); + } + + node = node.children.get(char)!; + } + + node.isEnd = true; + } + + /** + * TC: O(n) + * SC: O(n) + * */ + search(word: string): boolean { + let node = this.root; + + for (const char of word) { + if (!node.children.has(char)) { + return false; + } + + node = node.children.get(char)!; + } + + return node.isEnd; + } + + /** + * TC: O(n) + * SC: O(n) + * */ + startsWith(prefix: string): boolean { + let node = this.root; + + for (const char of prefix) { + if (!node.children.has(char)) { + return false; + } + + node = node.children.get(char)!; + } + + 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) + */ + +const trie = new Trie(); + +trie.insert("apple"); + +const tc1 = trie.search("apple"); // return True +console.info("🚀 : tolluset.ts:59: tc1=", tc1); + +const tc2 = trie.search("app"); // return False +console.info("🚀 : tolluset.ts:61: tc2=", tc2); + +const tc3 = trie.startsWith("app"); // return True +console.info("🚀 : tolluset.ts:63: tc3=", tc3); + +trie.insert("app"); + +const tc4 = trie.search("app"); // return True +console.info("🚀 : tolluset.ts:66: tc4=", tc4); From 3f79d029aa449819b06e877136c60d5133734cdb Mon Sep 17 00:00:00 2001 From: tolluset Date: Sat, 14 Sep 2024 15:57:20 +0900 Subject: [PATCH 7/8] solve: word break --- word-break/tolluset.ts | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 word-break/tolluset.ts diff --git a/word-break/tolluset.ts b/word-break/tolluset.ts new file mode 100644 index 000000000..00d145a9c --- /dev/null +++ b/word-break/tolluset.ts @@ -0,0 +1,40 @@ +/* + * TC: O(n^2) + * SC: O(n) + * */ +function wordBreak(s: string, wordDict: string[]): boolean { + const n = s.length; + const wordSet = new Set(wordDict); + const dp = Array(n + 1).fill(false); + + dp[0] = true; + + for (let i = 1; i <= n; i++) { + for (let j = 0; j < i; j++) { + if (dp[j] && wordSet.has(s.slice(j, i))) { + dp[i] = true; + break; + } + } + } + + return dp[n]; +} + +const tc1 = wordBreak("leetcode", ["leet", "code"]); // true +console.info("🚀 : tolluset.ts:17: tc1=", tc1); + +const tc2 = wordBreak("applepenapple", ["apple", "pen"]); // true +console.info("🚀 : tolluset.ts:20: tc2=", tc2); + +const tc3 = wordBreak("catsandog", ["cats", "dog", "sand", "and", "cat"]); // false +console.info("🚀 : tolluset.ts:23: tc3=", tc3); + +const tc4 = wordBreak("cars", ["car", "ca", "rs"]); // true +console.info("🚀 : tolluset.ts:27: tc4=", tc4); + +const tc5 = wordBreak("aaaaaaa", ["aaaa", "aaa"]); // true +console.info("🚀 : tolluset.ts:32: tc5=", tc5); + +const tc6 = wordBreak("cbca", ["bc", "ca"]); // false +console.info("🚀 : tolluset.ts:43: tc6=", tc6); From b773d4e154321b9f5c36de6a85422239872692ca Mon Sep 17 00:00:00 2001 From: tolluset Date: Sun, 15 Sep 2024 02:41:42 +0900 Subject: [PATCH 8/8] fix: adjust sc --- implement-trie-prefix-tree/tolluset.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/implement-trie-prefix-tree/tolluset.ts b/implement-trie-prefix-tree/tolluset.ts index d49eaca48..13a3c8145 100644 --- a/implement-trie-prefix-tree/tolluset.ts +++ b/implement-trie-prefix-tree/tolluset.ts @@ -35,7 +35,7 @@ class Trie { /** * TC: O(n) - * SC: O(n) + * SC: O(1) * */ search(word: string): boolean { let node = this.root; @@ -53,7 +53,7 @@ class Trie { /** * TC: O(n) - * SC: O(n) + * SC: O(1) * */ startsWith(prefix: string): boolean { let node = this.root;