From 23741c95f56c3237c55b06d60821fe4b029c62ba Mon Sep 17 00:00:00 2001 From: dipanjal Date: Sat, 23 Aug 2025 23:12:29 +0600 Subject: [PATCH 1/4] word break bruteforce solution --- leetcode/dp/Word_Break/recursion.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 leetcode/dp/Word_Break/recursion.py diff --git a/leetcode/dp/Word_Break/recursion.py b/leetcode/dp/Word_Break/recursion.py new file mode 100644 index 0000000..a4606b9 --- /dev/null +++ b/leetcode/dp/Word_Break/recursion.py @@ -0,0 +1,27 @@ +# Recursive bruteforce solution +# TC: O(2^n) +# SC: stack: O(n) + set: O(m) where m = number of words +class Solution: + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + wordSet = set(wordDict) + + maxLen = 0 + for word in wordSet: + maxLen = max(maxLen, len(word)) + + def canBreak(start: int, end: int) -> bool: + if end == len(s) - 1: + return s[start:end+1] in wordSet + + # exceeded the max window limit but we couldn't break + if (end - start) + 1 > maxLen: + return False + + + not_match = canBreak(start, end+1) + match = False + if s[start:end+1] in wordSet: + match = canBreak(start=end+1, end=end+1) + return match or not_match + + return canBreak(0, 0) \ No newline at end of file From e3db725b472acb394e5e769ad312152185701333 Mon Sep 17 00:00:00 2001 From: dipanjal Date: Sat, 23 Aug 2025 23:17:25 +0600 Subject: [PATCH 2/4] LC:139: word break memoized solution --- leetcode/dp/Word_Break/memoization.py | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 leetcode/dp/Word_Break/memoization.py diff --git a/leetcode/dp/Word_Break/memoization.py b/leetcode/dp/Word_Break/memoization.py new file mode 100644 index 0000000..9ebe216 --- /dev/null +++ b/leetcode/dp/Word_Break/memoization.py @@ -0,0 +1,32 @@ +# Recursive bruteforce solution +# TC: O(n) +# SC: stack: O(n) + set: O(n) +class Solution: + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + wordSet = set(wordDict) # O(1) + n = len(s) + + # unique combo: n * n -> O(n*n) + # memo: [n] * [n] -> O(n*n) + memo = [[-1] * n for _ in range(n)] + + def canBreak(start: int, end: int) -> bool: + # is it an overlapping sub + if memo[start][end] != -1: + return memo[start][end] + + # base case + if end == n-1: + memo[start][end] = s[start:end+1] in wordSet + return memo[start][end] + + # expanding the window + not_match = canBreak(start, end+1) + match = False + if s[start:end+1] in wordSet: + match = canBreak(start=end+1, end=end+1) + + memo[start][end] = not_match or match + return memo[start][end] + + return canBreak(0, 0) \ No newline at end of file From 8676e853f5419aeb2b0e89466b42270200ec3142 Mon Sep 17 00:00:00 2001 From: dipanjal Date: Sat, 23 Aug 2025 23:18:00 +0600 Subject: [PATCH 3/4] LC:139: word break tabulation solution --- leetcode/dp/Word_Break/tabulation.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 leetcode/dp/Word_Break/tabulation.py diff --git a/leetcode/dp/Word_Break/tabulation.py b/leetcode/dp/Word_Break/tabulation.py new file mode 100644 index 0000000..5752bd1 --- /dev/null +++ b/leetcode/dp/Word_Break/tabulation.py @@ -0,0 +1,23 @@ +# Recursive bruteforce solution +# TC: O(n) +# SC: set: O(n) + memo: O(n^2) +class Solution: + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + wordSet = set(wordDict) # O(1) + n = len(s) + + memo = [[False] * n for _ in range(n)] + # start => col + # end => row + for start in range(n): + memo[n-1][start] = s[start:n] in wordSet + + for end in range(n-2, -1, -1): + for start in range(n): + not_match = memo[end+1][start] # canBreak(start, end+1) + match = False + if s[start:end+1] in wordSet: + match = memo[end+1][end+1] # canBreak(start=end+1, end=end+1) + memo[end][start] = not_match or match + + return memo[0][0] \ No newline at end of file From b24d3a5e5d3dba2db0576db5beae6f4b5f1ab07e Mon Sep 17 00:00:00 2001 From: dipanjal Date: Sat, 23 Aug 2025 23:18:35 +0600 Subject: [PATCH 4/4] LC:139: word break space optimized --- leetcode/dp/Word_Break/space_optimization.py | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 leetcode/dp/Word_Break/space_optimization.py diff --git a/leetcode/dp/Word_Break/space_optimization.py b/leetcode/dp/Word_Break/space_optimization.py new file mode 100644 index 0000000..333836d --- /dev/null +++ b/leetcode/dp/Word_Break/space_optimization.py @@ -0,0 +1,26 @@ +# Recursive bruteforce solution +# TC: O(n) +# SC: set: O(n) + memo: O(n) + O(n) ~ O(n) +class Solution: + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + wordSet = set(wordDict) # O(1) + n = len(s) + + # start => col + # end => row + next_row = [False] * n + for start in range(n): + next_row[start] = s[start:n] in wordSet + + # end=3 + for end in range(n-2, -1, -1): + curr = [False] * n + for start in range(n): + not_match = next_row[start] # canBreak(start, end+1) + match = False + if s[start:end+1] in wordSet: + match = next_row[end+1] # canBreak(start=end+1, end=end+1) + curr[start] = not_match or match + next_row = curr + + return next_row[0] \ No newline at end of file