Word Break II

Return all sentences s can be segmented into — memoized DFS keyed by start index.

Hard
Time O(2^n + paths * n) Space O(n)
LeetCode
4 min read
dp memoization string

Problem#

Return all ways to segment s into dictionary words, joined with spaces.

Examples#

  • s = "catsanddog", wordDict = ["cat","cats","and","sand","dog"]["cats and dog","cat sand dog"]

Constraints#

  • 1 <= n <= 20.

Approach#

Memoized DFS: for each start, cache the list of valid sentences from s[start:]. Combine each prefix word with every sentence from the suffix.

Solution#

Word Break II
class Solution {
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> dict(wordDict.begin(), wordDict.end());
unordered_map<int, vector<string>> memo;
function<vector<string>(int)> dfs = [&](int start) -> vector<string> {
if (memo.count(start)) return memo[start];
if (start == (int)s.size()) return {""};
vector<string> out;
for (int end = start + 1; end <= (int)s.size(); ++end) {
string word = s.substr(start, end - start);
if (!dict.count(word)) continue;
for (auto& tail : dfs(end)) {
out.push_back(word + (tail.empty() ? "" : " " + tail));
}
}
return memo[start] = out;
};
return dfs(0);
}
};

Editorial#

Memoization on start ensures each suffix is solved at most once. Without it, the DFS is exponential. The empty-string sentinel at start == n cleanly terminates the recursion and lets us avoid trailing spaces.

Complexity#

  • Time: O(2^n + paths × n).
  • Space: O(n × paths).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.