Word Break Problem in DSA Javascript - Time & Space Complexity
We want to know how the time needed to solve the Word Break Problem changes as the input grows.
Specifically, how does checking if a string can be split into dictionary words scale with longer strings and bigger dictionaries?
Analyze the time complexity of the following code snippet.
function wordBreak(s, wordDict) {
const dp = Array(s.length + 1).fill(false);
dp[0] = true;
for (let i = 1; i <= s.length; i++) {
for (let j = 0; j < i; j++) {
if (dp[j] && wordDict.has(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[s.length];
}
This code checks if the string s can be split into words from wordDict by building up a boolean array dp.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops checking all substrings of
s. - How many times: Outer loop runs
ntimes, inner loop runs up toitimes, totaling roughlynΒ²substring checks. - Each substring check uses
substringandwordDict.has(), which isO(k)for substring extraction andO(1)average for dictionary lookup.
As the string length n grows, the number of substring checks grows roughly with the square of n.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 100 substring checks |
| 100 | About 10,000 substring checks |
| 1000 | About 1,000,000 substring checks |
Pattern observation: Doubling the input length roughly quadruples the number of operations.
Time Complexity: O(n^3)
This means the time grows roughly with the cube of the string length due to substring extraction inside nested loops.
[X] Wrong: "The solution runs in linear time because it just loops through the string once."
[OK] Correct: There are nested loops checking all possible substrings, so the work grows much faster than just one pass.
Understanding this time complexity helps you explain how your solution scales and shows you can analyze nested loops clearly.
"What if we used a Trie data structure for the dictionary instead of a hash set? How would the time complexity change?"
Practice
s and a dictionary of words wordDict?Solution
Step 1: Understand the problem statement
The Word Break Problem asks whether the entire stringscan be split into parts where each part is a word from the dictionarywordDict.Step 2: Compare options with the problem definition
Ifscan be segmented into a space-separated sequence of one or more dictionary words correctly states the problem as checking ifscan be segmented into dictionary words. Other options describe partial or different checks.Final Answer:
Ifscan be segmented into a space-separated sequence of one or more dictionary words -> Option BQuick Check:
Word Break Problem = segmentation check [OK]
- Thinking it checks for substring presence only
- Confusing exact match with segmentation
- Assuming reversal or partial matches
wordBreak in JavaScript that takes two parameters: s (string) and wordDict (array)?Solution
Step 1: Recall JavaScript function syntax
In JavaScript, functions are declared using thefunctionkeyword followed by the name and parentheses enclosing parameters.Step 2: Check each option's syntax
function wordBreak(s, wordDict) {} uses correct JavaScript syntax. def wordBreak(s, wordDict): {} is Python syntax. func wordBreak(s, wordDict) {} resembles Go syntax. function wordBreak[s, wordDict] {} uses incorrect brackets.Final Answer:
function wordBreak(s, wordDict) {} -> Option DQuick Check:
JS function syntax = function name(params) {} [OK]
- Using Python or other language syntax
- Using square brackets instead of parentheses
- Missing function keyword
const s = "leetcode";
const wordDict = ["leet", "code"];
function wordBreak(s, wordDict) {
const dp = Array(s.length + 1).fill(false);
dp[0] = true;
for (let i = 1; i <= s.length; i++) {
for (let j = 0; j < i; j++) {
if (dp[j] && wordDict.includes(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[s.length];
}
console.log(wordBreak(s, wordDict));Solution
Step 1: Understand the dynamic programming array dp
dp[i] means if substring s[0..i-1] can be segmented. dp[0] = true means empty string is segmentable.Step 2: Trace the loops and substring checks
For s = "leetcode", wordDict = ["leet", "code"], dp updates to true at dp[4] ("leet") and dp[8] ("leetcode") because both substrings are in wordDict.Final Answer:
true -> Option CQuick Check:
"leetcode" split as "leet" + "code" = true [OK]
- Confusing substring indices
- Not initializing dp[0] to true
- Assuming partial matches are enough
function wordBreak(s, wordDict) {
const dp = Array(s.length).fill(false);
dp[0] = true;
for (let i = 1; i <= s.length; i++) {
for (let j = 0; j < i; j++) {
if (dp[j] && wordDict.includes(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[s.length];
}Solution
Step 1: Check dp array initialization
dp array length should be s.length + 1 to include dp[s.length] index. Current length s.length causes out-of-bound errors.Step 2: Verify dp usage and return statement
dp[s.length] is accessed at return, but dp array does not have that index, causing undefined or error.Final Answer:
dp array length is incorrect; should be s.length + 1 -> Option AQuick Check:
dp length = s.length + 1 for full coverage [OK]
- Using dp length equal to s.length only
- Misunderstanding dp index meaning
- Ignoring off-by-one errors
s = "applepenapple" and dictionary wordDict = ["apple", "pen"], which of the following modifications to the Word Break algorithm will allow it to return true only if all possible segmentations of s are valid dictionary words (not just one)?Solution
Step 1: Understand current algorithm behavior
The current algorithm returns true if at least one segmentation exists. It does not check all segmentations.Step 2: Modify dp to count all valid segmentations
By storing counts of valid segmentations at each dp index, we can compare total segmentations to valid ones. Returning true only if all segmentations are valid requires counting and comparing.Final Answer:
Change dp to store counts of valid segmentations and check if count equals total segmentations -> Option AQuick Check:
Counting all segmentations ensures all are valid [OK]
- Assuming one valid segmentation means all are valid
- Ignoring need to track all segmentation paths
- Confusing substring search optimization with segmentation count
Ready to prove it?
Pass the test and this pattern moves unknown
