Explain the Problem
Given a string s
and a dictionary of strings wordDict
, add spaces in s
to construct a sentence where each word is a valid dictionary word. Return all such possible sentences in any order.
Example:
Input: s = "catsanddog"
, wordDict = ["cat", "cats", "and", "sand", "dog"]
Output:
[
"cats and dog",
"cat sand dog"
]
1) Explain the problem
Given a string s
and a dictionary of words wordDict
, add spaces in s
to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.
2) Short easy to remember solution/approach
Use backtracking to try different word splits.
Use memoization to store already computed results for substrings to avoid redundant computations.
3) Solution in JavaScript with code commenting
function wordBreak(s, wordDict) {
const wordSet = new Set(wordDict);
const memo = new Map();
function backtrack(start) {
if (memo.has(start)) {
return memo.get(start);
}
const result = [];
if (start === s.length) {
result.push("");
}
for (let end = start + 1; end <= s.length; end++) {
const word = s.slice(start, end);
if (wordSet.has(word)) {
const subSentences = backtrack(end);
for (const subSentence of subSentences) {
result.push(word + (subSentence ? " " + subSentence : ""));
}
}
}
memo.set(start, result);
return result;
}
return backtrack(0);
}
// Example usage:
const s = "catsanddog";
const wordDict = ["cat", "cats", "and", "sand", "dog"];
console.log(wordBreak(s, wordDict));
// Output: ["cats and dog", "cat sand dog"]
4) Explanation the solution in an easy-to-understand way with real-life example
Imagine you have a long word like "catsanddog" and a list of valid smaller words like ["cat", "cats", "and", "sand", "dog"]. Your task is to break down the long word into a sentence where every smaller word comes from your list.
Think of it like a puzzle. You have the pieces ("cat", "cats", "and", "sand", "dog"), and you need to figure out all the ways to put these pieces together to form the big word "catsanddog".
5) Code explanation in pointers
Initialize word set: Convert the word dictionary into a set for quick lookup.
Memoization map: Use a map to store results of already processed substrings.
Backtracking function: This function tries to split the string into valid words.
Base case: If the start index reaches the end of the string, add an empty string to results.
Loop through substrings: Try every possible substring starting from the current index.
Check word validity: If the current substring is a valid word, recursively process the remaining part of the string.
Combine results: Combine the current word with valid sentences formed from the remaining substring.
Store results in memo: Save the results for the current start index in the memo map.
Return results: Return all possible sentences.
6) Complexities
Time complexity: (O(n^3)) where (n) is the length of the string. This is due to the multiple recursive calls and substring operations.
Space complexity: (O(n^3)) due to the memoization map and recursion stack.