1. Memoized DFS Recursion
Intuition
Define canBreak(start) checking if s[start...] can be segmented. Base case: start == s.length returns true. For end from start + 1 to s.length: if s[start...end-1] is in dictionary and canBreak(end) is true, return true. Memoize memo[start].
When to apply: Basic top-down conceptual formulation.
Algorithm
- Initialize
memoarray of sizes.lengthwith -1. - Helper
dfs(start): - If
start == s.length: return true. - If
memo[start] != -1: returnmemo[start] == 1. - For
endfromstart + 1tos.length: - If
dict.contains(s[start...end-1]) && dfs(end):memo[start] = 1; return true. -
memo[start] = 0; return false.
Memoized DFS Recursion
2 of 2 questions left todayObservation: Initial call canBreak(start=0)
Observation: Initial call canBreak(start=0).
Decision: Test dictionary membership for candidate prefixes: 'l', 'le', 'lee' are not in dictionary.
Invariant: A valid segmentation requires every partitioned substring to exist in the dictionary.
#include <iostream>#include <string>#include <vector>#include <unordered_set> class Solution { int memo[305]; bool dfs(int start, const std::string& s, const std::unordered_set<std::string>& dict) { if (start == (int)s.size()) return true; if (memo[start] != -1) return memo[start]; for (int end = start + 1; end <= (int)s.size(); ++end) { std::string sub = s.substr(start, end - start); if (dict.count(sub) && dfs(end, s, dict)) { return memo[start] = 1; } } return memo[start] = 0; }public: bool wordBreak(std::string s, std::vector<std::string>& wordDict) { std::unordered_set<std::string> dict(wordDict.begin(), wordDict.end()); for (int i = 0; i <= (int)s.size(); ++i) memo[i] = -1; return dfs(0, s, dict); }}; int main() { Solution sol; std::vector<std::string> dict = {"leet", "code"}; std::cout << (sol.wordBreak("leetcode", dict) ? "true" : "false") << std::endl; // true return 0;}Time & Space Complexity
- Time complexity:
O(N^2)— N subproblems, each checking up to N prefixes. - Space complexity:
O(N)
Why Brute Force Doesn't Scale:
Forward Trie traversal from reachable indices eliminates redundant substring allocations.
1D boolean array + compact 26-ary Trie.