diff --git a/best-time-to-buy-and-sell-stock/Yjason-K.ts b/best-time-to-buy-and-sell-stock/Yjason-K.ts new file mode 100644 index 000000000..8eae8e5fc --- /dev/null +++ b/best-time-to-buy-and-sell-stock/Yjason-K.ts @@ -0,0 +1,28 @@ +/** + * 최대 이익을 계산하는 함수 + * @param {number[]} prices + * @returns {number} + * + * 시간 복잡도 : O(n) (n: 주식 가격 배열의 길이) + * 공간 복잡도 : 0(1) (추가 자료구조 X) + */ +function maxProfit(prices: number[]): number { + let minPrice = 100001; // 지금까지의 최소 가격 + let maxProfit = 0; // 최대 이익 + + for (let price of prices) { + // 최소 가격 갱신 + if (price < minPrice) { + minPrice = price; + } + + // 현재 가격에서 최소 가격을 뺀 이익이 최대 이익보다 크다면 갱신 + const potentialProfit = price - minPrice; + if (potentialProfit > maxProfit) { + maxProfit = potentialProfit; + } + } + + return maxProfit; +} + diff --git a/encode-and-decode-strings/Yjason-K.ts b/encode-and-decode-strings/Yjason-K.ts new file mode 100644 index 000000000..92fa77b0b --- /dev/null +++ b/encode-and-decode-strings/Yjason-K.ts @@ -0,0 +1,28 @@ +/** + * @description 문자열 배열을 하나의 문자열로 인코딩합니다. + * @param {string[]} strs - 문자열 배열 + * @returns {string} 인코딩된 문자열 + * + * 시간 복잡도: O(N) + * - N은 입력 배열의 모든 문자열 길이의 합 + * 공간 복잡도: O(1) + * - 추가 메모리 사용 없음 + */ +function encode(strs: string[]): string { + return strs.join(':'); + } + + /** + * @description 인코딩된 문자열을 다시 문자열 배열로 디코딩합니다. + * @param {string} s - 인코딩된 문자열 + * @returns {string[]} 디코딩된 문자열 배열 + * + * 시간 복잡도: O(N) + * - N은 입력 문자열의 길이 + * 공간 복잡도: O(1) + * - 추가 메모리 사용 없음 + */ + function decode(s: string): string[] { + return s.split(':'); + } + diff --git a/group-anagrams/Yjason-K.ts b/group-anagrams/Yjason-K.ts new file mode 100644 index 000000000..a4a2dd744 --- /dev/null +++ b/group-anagrams/Yjason-K.ts @@ -0,0 +1,34 @@ +/** + * 주어진 문자열 배열에서 Anagram을 그룹화 해서 배열 만들기 + * @param {string[]} strs - 문자열 배열 + * @returns {string[][]} Anagram을 그룹 배열 + * + * 문자열들을 정렬해서 Map에 담아서 존재하면 그 때의 문자를 value로 추가 + * 존재하지 않으면 새로운 배열을 value로 추가 + * + * 시간 복잡도: O(N * M * log(M)) + * - N은 문자열 배열의 길이 + * - M은 각 문자열의 평균 길이 (정렬 시간 때문) + * 공간 복잡도: O(N * M) + * - 해시맵에 저장되는 문자열 그룹 때문 + */ +function groupAnagrams(strs: string[]): string[][] { + const anagramMap: Map = new Map(); + for (const str of strs) { + + // 정렬된 문자열 + const sortedStr = str.split('').sort().join(''); + + // 정렬된 문자열이 존재하는 않는 경우 + if (!anagramMap.has(sortedStr)) { + anagramMap.set(sortedStr, []) + } + + // 정렬된 문자열을 key로 하는 value str 추가 + anagramMap.get(sortedStr)?.push(str); + } + + // anagramMap에서 values만 배열로해서 출력 + return Array.from(anagramMap.values()) +} + diff --git a/word-break/Yjason-K.ts b/word-break/Yjason-K.ts new file mode 100644 index 000000000..36c7dd656 --- /dev/null +++ b/word-break/Yjason-K.ts @@ -0,0 +1,39 @@ +/** + * 주어진 문자열이 단어 사전에 있는 단어들로 나누어질 수 있는지 확인합니다. + * + * + * @param {string} s - 확인할 문자열 + * @param {string[]} wordDict - 단어 사전 + * @returns {boolean} 문자열이 단어로 완벽히 나누어질 수 있으면 `true`, 아니면 `false` + * + * 시간 복잡성 O(n * m * k) + * - n: 문자열 s 길이 + * - m: 단어 사전 길이 + * - k: 단어 사전 내 단어 길이 + * + * 공간 복잡성 O(n) + * - 메모이제이션(memo) 및 재귀 호출 스택 크기가 문자열 길이 n에 비례. + */ +function wordBreak(s: string, wordDict: string[]): boolean { + const memo: Record = {}; + + /** + * @param {number} start - 현재 시작 idx + * @returns {boolean} 주어진 idx 부터 문자열을 나눌 수 있으면 true + */ + const dfs = (start: number): boolean => { + if (start in memo) return memo[start]; + if (start === s.length) return (memo[start] = true); + + for (const word of wordDict) { + if (s.startsWith(word, start) && dfs(start + word.length)) { + return (memo[start] = true); + } + } + + return (memo[start] = false); + }; + + return dfs(0); +} +