diff --git a/best-time-to-buy-and-sell-stock/hyer0705.ts b/best-time-to-buy-and-sell-stock/hyer0705.ts new file mode 100644 index 000000000..98bb22149 --- /dev/null +++ b/best-time-to-buy-and-sell-stock/hyer0705.ts @@ -0,0 +1,14 @@ +function maxProfit(prices: number[]): number { + let minPrice = Infinity; + let maxProfit = 0; + + for (const price of prices) { + if (price < minPrice) { + minPrice = price; + } else { + maxProfit = Math.max(maxProfit, price - minPrice); + } + } + + return maxProfit; +} diff --git a/encode-and-decode-strings/hyer0705.ts b/encode-and-decode-strings/hyer0705.ts new file mode 100644 index 000000000..46a43c229 --- /dev/null +++ b/encode-and-decode-strings/hyer0705.ts @@ -0,0 +1,47 @@ +class Solution { + private DELIMITER = "*"; + + /** + * @param strs: a list of strings + * @returns: encodes a list of strings to a single string. + */ + public encode(strs: string[]): string { + let encoded = ""; + + for (const str of strs) { + encoded += `${str.length}${this.DELIMITER}${str}`; + } + + return encoded; + } + + /** + * @param str: A string + * @returns: decodes a single string to a list of strings + */ + public decode(str: string): string[] { + const decoded: string[] = []; + + let stack: string[] = []; + let pointer = 0; + + while (pointer < str.length) { + const char = str[pointer]; + + if (char === this.DELIMITER) { + let strLength: number = Number(stack.join("")); + stack = []; + + const word = str.substring(pointer + 1, pointer + 1 + strLength); + pointer = pointer + 1 + strLength; + + decoded.push(word); + } else { + stack.push(char); + pointer++; + } + } + + return decoded; + } +} diff --git a/group-anagrams/hyer0705.ts b/group-anagrams/hyer0705.ts new file mode 100644 index 000000000..bdd130842 --- /dev/null +++ b/group-anagrams/hyer0705.ts @@ -0,0 +1,15 @@ +function groupAnagrams(strs: string[]): string[][] { + const anagramsMap = new Map(); + + for (const word of strs) { + const anagramKey = [...word].sort().join(); + + if (anagramsMap.has(anagramKey)) { + anagramsMap.get(anagramKey)!.push(word); + } else { + anagramsMap.set(anagramKey, [word]); + } + } + + return Array.from(anagramsMap.values()); +} diff --git a/implement-trie-prefix-tree/hyer0705.ts b/implement-trie-prefix-tree/hyer0705.ts new file mode 100644 index 000000000..16b3374c3 --- /dev/null +++ b/implement-trie-prefix-tree/hyer0705.ts @@ -0,0 +1,69 @@ +class TNode { + isEndOf: boolean; + children: Map; + + constructor() { + this.isEndOf = false; + this.children = new Map(); + } +} + +class Trie { + private root: TNode; + + constructor() { + this.root = new TNode(); + } + + insert(word: string): void { + let currentNode: TNode = this.root; + + for (const ch of word) { + if (currentNode.children.has(ch)) { + currentNode = currentNode.children.get(ch)!; + } else { + const newNode = new TNode(); + + currentNode.children.set(ch, newNode); + currentNode = currentNode.children.get(ch)!; + } + } + currentNode.isEndOf = true; + } + + search(word: string): boolean { + let currentNode = this.root; + + for (const ch of word) { + if (!currentNode.children.has(ch)) { + return false; + } + + currentNode = currentNode.children.get(ch)!; + } + + return currentNode.isEndOf; + } + + startsWith(prefix: string): boolean { + let currentNode = this.root; + + for (const ch of prefix) { + if (!currentNode.children.has(ch)) { + return false; + } + + currentNode = currentNode.children.get(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) + */ diff --git a/word-break/hyer0705.ts b/word-break/hyer0705.ts new file mode 100644 index 000000000..9226a16f6 --- /dev/null +++ b/word-break/hyer0705.ts @@ -0,0 +1,93 @@ +// using set +function wordBreak(s: string, wordDict: string[]): boolean { + const sLen = s.length; + + const dp: boolean[] = new Array(sLen + 1).fill(false); + dp[0] = true; + + const wordSet = new Set(wordDict); + + for (let i = 1; i <= sLen; i++) { + for (let j = 0; j < i; j++) { + if (dp[j] && wordSet.has(s.substring(j, i))) { + dp[i] = true; + break; + } + } + } + + return dp[sLen]; +} + +// using trie +class TNode { + isEndOf: boolean; + children: Map; + + constructor() { + this.isEndOf = false; + this.children = new Map(); + } +} + +class Trie { + root: TNode; + + constructor() { + this.root = new TNode(); + } + + insert(word: string): void { + let currentNode = this.root; + + for (const ch of word) { + if (!currentNode.children.has(ch)) { + currentNode.children.set(ch, new TNode()); + } + + currentNode = currentNode.children.get(ch)!; + } + + currentNode.isEndOf = true; + } + + search(word: string): boolean { + let currentNode = this.root; + + for (const ch of word) { + if (!currentNode.children.has(ch)) { + return false; + } + + currentNode = currentNode.children.get(ch)!; + } + + return currentNode.isEndOf; + } +} + +function wordBreak(s: string, wordDict: string[]): boolean { + const sLen = s.length; + + const dp: boolean[] = new Array(sLen + 1).fill(false); + dp[0] = true; + + const trie = new Trie(); + + for (const word of wordDict) { + trie.insert(word); + } + + for (let i = 1; i <= sLen; i++) { + for (let j = 0; j < i; j++) { + if (dp[j]) { + if (trie.search(s.substring(j, i))) { + dp[i] = true; + break; + } + } + } + } + + return dp[sLen]; +}