From de4895149678a27b1c7968d0f6df39ee35d7a17c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=98=81=EC=9E=AC?= <gomgom0324@gmail.com>
Date: Sat, 11 Jan 2025 12:51:18 +0900
Subject: [PATCH] add: solve #271 Word Break with ts

---
 word-break/Yjason-K.ts | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 word-break/Yjason-K.ts

diff --git a/word-break/Yjason-K.ts b/word-break/Yjason-K.ts
new file mode 100644
index 000000000..c4185c581
--- /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<number, boolean> = {};
+
+    /**
+     * @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);
+}
+