diff --git a/best-time-to-buy-and-sell-stock/soobing2.ts b/best-time-to-buy-and-sell-stock/soobing2.ts new file mode 100644 index 000000000..8141605cd --- /dev/null +++ b/best-time-to-buy-and-sell-stock/soobing2.ts @@ -0,0 +1,21 @@ +/** + * 문제 유형 + * - Array + * + * 문제 설명 + * - 주식을 가장 싸게 사서 비싸게 팔수 있는 경우 찾기 + * + * 아이디어 + * 1) 최소값을 찾고 그 이후의 값 중 최대값을 찾는다. + * + */ +function maxProfit(prices: number[]): number { + let min = prices[0]; + let maxProfit = 0; + + for (let i = 1; i < prices.length; i++) { + min = Math.min(min, prices[i]); + maxProfit = Math.max(prices[i] - min, maxProfit); + } + return maxProfit; +} diff --git a/encode-and-decode-strings/soobing2.ts b/encode-and-decode-strings/soobing2.ts new file mode 100644 index 000000000..1076e9565 --- /dev/null +++ b/encode-and-decode-strings/soobing2.ts @@ -0,0 +1,42 @@ +/** + * 문제 유형 + * - String + * + * 문제 설명 + * - 문자열 인코딩과 디코딩 + * + * 아이디어 + * 1) "길이 + # + 문자열" 형태로 인코딩 + * + */ +class Solution { + /** + * @param {string[]} strs + * @returns {string} + */ + encode(strs) { + return strs.map((str) => `${str.length}#${str}`).join(""); + } + + /** + * @param {string} str + * @returns {string[]} + */ + decode(str) { + const result = []; + let tempStr = str; + while (tempStr.length) { + let i = 0; + + while (tempStr[i] !== "#") { + i++; + } + + const length = Number(tempStr.slice(0, i)); + const currentStr = tempStr.slice(i + 1, i + 1 + length); + result.push(currentStr); + tempStr = tempStr.slice(length + i + 1); + } + return result; + } +} diff --git a/group-anagrams/soobing2.ts b/group-anagrams/soobing2.ts new file mode 100644 index 000000000..f1825a864 --- /dev/null +++ b/group-anagrams/soobing2.ts @@ -0,0 +1,20 @@ +/** + * 문제 유형 + * - String + * + * 문제 설명 + * - 애너그램 그룹화 + * + * 아이디어 + * 1) 각 문자열을 정렬하여 키로 사용하고 그 키에 해당하는 문자열 배열을 만들어 리턴 + * + */ +function groupAnagrams(strs: string[]): string[][] { + const map = new Map(); + + for (let i = 0; i < strs.length; i++) { + const key = strs[i].split("").sort().join(""); + map.set(key, [...(map.get(key) ?? []), strs[i]]); + } + return [...map.values()]; +} diff --git a/implement-trie-prefix-tree/soobing2.ts b/implement-trie-prefix-tree/soobing2.ts new file mode 100644 index 000000000..b484d2227 --- /dev/null +++ b/implement-trie-prefix-tree/soobing2.ts @@ -0,0 +1,67 @@ +/** + * 문제 유형 + * - Trie 구현 (문자열 검색) + * + * 문제 설명 + * - 문자열 검색/추천/자동완성에서 자주 사용하는 자료구조 Trie 구현 + * + * 아이디어 + * 1) 문자열의 각 문자를 TrieNode 클래스의 인스턴스로 표현s + * + */ +class TrieNode { + children: Map; + isEnd: boolean; + + constructor() { + this.children = new Map(); + this.isEnd = false; + } +} + +class Trie { + root: TrieNode; + constructor() { + this.root = new TrieNode(); + } + + 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; + } + + // isEnd 까지 확인이 필요 + search(word: string): boolean { + const node = this._findNode(word); + return node !== null && node.isEnd; + } + + // isEnd까지 확인 필요 없고 존재 여부만 확인 필요 + startsWith(prefix: string): boolean { + return this._findNode(prefix) !== null; + } + + private _findNode(word: string): TrieNode | null { + let node = this.root; + for (const char of word) { + if (!node.children.get(char)) return null; + node = node.children.get(char)!; + } + + return node; + } +} + +/** + * 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/soobing2.ts b/word-break/soobing2.ts new file mode 100644 index 000000000..e7fa4c5a3 --- /dev/null +++ b/word-break/soobing2.ts @@ -0,0 +1,26 @@ +/** + * 유형 + * - dp (뒤쪽 단어를 쪼갤 수 있어야 전체를 쪼갤 수 있다.) + * + * 문제 설명 + * - 문자열 s를 주어진 wordDict에 있는 단어로 쪼갤 수 있는가? + * + * 아이디어 + * - dp[i] = s[i]로 시작하는 문자열이 wordDict에 있는 단어로 쪼갤 수 있는지 여부 + */ + +function wordBreak(s: string, wordDict: string[]): boolean { + const dp = new Array(s.length + 1).fill(false); + + dp[s.length] = true; + + for (let i = s.length - 1; i >= 0; i--) { + for (const word of wordDict) { + if (i + word.length <= s.length && s.slice(i, i + word.length) === word) { + dp[i] = dp[i + word.length]; + } + if (dp[i]) break; + } + } + return dp[0]; +}