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); 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..1ec857d67 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/tolluset.ts @@ -0,0 +1,63 @@ +/* + * 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) + * */ +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 diff --git a/group-anagrams/tolluset.ts b/group-anagrams/tolluset.ts new file mode 100644 index 000000000..2efb88632 --- /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 = new Map(); + + const strSort = (str: string) => str.split("").sort().join(""); + + for (const str of strs) { + const sortedStr = strSort(str); + + if (map.has(sortedStr)) { + map.get(sortedStr)!.push(str); + } else { + map.set(sortedStr, [str]); + } + } + + return Array.from(map.values()); +} + +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); diff --git a/implement-trie-prefix-tree/tolluset.ts b/implement-trie-prefix-tree/tolluset.ts new file mode 100644 index 000000000..13a3c8145 --- /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(1) + * */ + 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(1) + * */ + 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); 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);