diff --git a/best-time-to-buy-and-sell-stock/Jeehay28.ts b/best-time-to-buy-and-sell-stock/Jeehay28.ts new file mode 100644 index 000000000..4333016aa --- /dev/null +++ b/best-time-to-buy-and-sell-stock/Jeehay28.ts @@ -0,0 +1,21 @@ +// Time Complexity: O(n), where n is the length of the prices array +// Space Complexity: O(1) + +function maxProfit(prices: number[]): number { + // input: an array prices, prices[i] = the stock price of ith day + // output: the maximum profit || 0 + + // prices = [7, 1, 5, 3, 6, 4] + // buy = 1, sell = 6, profit = 6 -1 = 5 + + let minBuy = prices[0]; + let maxProfit = 0; + + for (let i = 1; i < prices.length; i++) { + minBuy = Math.min(prices[i], minBuy); + maxProfit = Math.max(prices[i] - minBuy, maxProfit); + } + + return maxProfit; +} + diff --git a/group-anagrams/Jeehay28.ts b/group-anagrams/Jeehay28.ts new file mode 100644 index 000000000..baa0409f3 --- /dev/null +++ b/group-anagrams/Jeehay28.ts @@ -0,0 +1,62 @@ +// Approach 2 +// Time Complexity: O(n * L), where n = number of strings in strs, L = maximum length of a string in strs +// Space Complexity: O(n * L) + +function groupAnagrams(strs: string[]): string[][] { + + let sorted: { [key: string]: string[] } = {} + + for (const str of strs) { + + const arr = Array.from({ length: 26 }, () => 0) + + for (const ch of str) { + arr[ch.charCodeAt(0) - "a".charCodeAt(0)] += 1 + } + + // const key = arr.join(""); // This can lead to key collisions. + const key = arr.join("#"); // ✅ + + if (!sorted[key]) { + sorted[key] = [] + } + + sorted[key].push(str) + } + + return Object.values(sorted); +}; + + +// Approach 1 +// Time Complexity: O(n * LlogL), where n = number of strings, L = average length of the strings +// Space Complexity: O(n * L) + +// function groupAnagrams(strs: string[]): string[][] { +// // input: an array of strings, strs +// // output: the anagrams + +// // eat -> e, a, t -> a, e, t +// // tea -> t, e, a -> a, e, t +// // ate -> a, t, e -> a, e, t + +// let map = new Map(); +// let result: string[][] = []; + +// for (const str of strs) { +// const temp = str.split("").sort().join(""); + +// if (map.has(temp)) { +// map.set(temp, [...map.get(temp)!, str]); +// } else { +// map.set(temp, [str]); +// } +// } + +// for (const el of map.values()) { +// result.push(el); +// } + +// return result; +// } + diff --git a/implement-trie-prefix-tree/Jeehay28.ts b/implement-trie-prefix-tree/Jeehay28.ts new file mode 100644 index 000000000..be37c719a --- /dev/null +++ b/implement-trie-prefix-tree/Jeehay28.ts @@ -0,0 +1,64 @@ +// Time Complexity: O(n) + +class TrieNode { + children: { [key: string]: TrieNode }; + ending: boolean; + + constructor(ending = false) { + this.children = {}; + this.ending = ending; + } +} + +class Trie { + root: TrieNode; + + constructor() { + this.root = new TrieNode(); + } + + insert(word: string): void { + let node = this.root; + + for (const ch of word) { + if (!(ch in node.children)) { + node.children[ch] = new TrieNode(); + } + node = node.children[ch]; + } + node.ending = true; + } + + search(word: string): boolean { + let node = this.root; + + for (const ch of word) { + if (!(ch in node.children)) { + return false; + } + node = node.children[ch]; + } + return node.ending; + } + + startsWith(prefix: string): boolean { + let node = this.root; + + for (const ch of prefix) { + if (!(ch in node.children)) { + return false; + } + + node = node.children[ch]; + } + 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) + */