Word Break Problem in DSA Java - Time & Space Complexity
We want to understand 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 string length?
Analyze the time complexity of the following code snippet.
public boolean wordBreak(String s, List<String> wordDict) {
Set<String> wordSet = new HashSet<>(wordDict);
boolean[] dp = new boolean[s.length() + 1];
dp[0] = true;
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && wordSet.contains(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}
This code checks if the string can be segmented into dictionary words using dynamic programming.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops where for each position in the string, we check all previous positions.
- How many times: Outer loop runs n times (string length), inner loop runs up to n times, so up to n x n checks.
As the string length grows, the number of checks grows roughly with the square of the length.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 100 checks |
| 100 | About 10,000 checks |
| 1000 | About 1,000,000 checks |
Pattern observation: Doubling the string length roughly quadruples the work.
Time Complexity: O(n^3)
This means the time grows roughly with the cube of the string length due to substring operations.
[X] Wrong: "The solution only checks each character once, so it must be O(n)."
[OK] Correct: Because for each position, it checks all previous positions, leading to nested loops and more work than just one pass.
Understanding this time complexity helps you explain how dynamic programming improves over naive recursion and shows your grasp of nested loops and their cost.
"What if we used a Trie data structure instead of a HashSet for word lookup? How would the time complexity change?"
Practice
Word Break Problem in algorithms?Solution
Step 1: Understand the problem statement
The Word Break Problem asks if a given string can be split into one or more words found in a dictionary.Step 2: Identify the goal
The goal is to verify if such segmentation is possible, not to count or reverse characters.Final Answer:
To check if a string can be segmented into valid dictionary words -> Option AQuick Check:
Word Break Problem = Check segmentation [OK]
- Confusing with string reversal
- Thinking it counts vowels
- Assuming it finds longest word
Solution
Step 1: Identify expected return type
The Word Break Problem returns true or false, so return type should be boolean.Step 2: Check parameter types
The input string is String, and dictionary can be List or Set of strings. public boolean wordBreak(String s, List<String> wordDict) uses List<String> and boolean return, which is correct.Final Answer:
public boolean wordBreak(String s, List<String> wordDict) -> Option BQuick Check:
Return type boolean + List parameter = public boolean wordBreak(String s, List<String> wordDict) [OK]
- Using int or void as return type
- Returning String instead of boolean
- Using wrong parameter types
import java.util.*;
public class Solution {
public static boolean wordBreak(String s, List<String> wordDict) {
boolean[] dp = new boolean[s.length() + 1];
dp[0] = true;
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && wordDict.contains(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}
public static void main(String[] args) {
List<String> dict = Arrays.asList("leet", "code");
System.out.println(wordBreak("leetcode", dict));
}
}Solution
Step 1: Understand the dynamic programming logic
The dp array tracks if substring up to index i can be segmented. Initially dp[0] = true.Step 2: Trace the input "leetcode" with dictionary ["leet", "code"]
"leet" matches s[0:4], so dp[4] = true. Then "code" matches s[4:8], so dp[8] = true. Hence, dp[s.length()] = true.Final Answer:
true -> Option AQuick Check:
"leetcode" segmented = true [OK]
- Assuming false because of substring indexing
- Confusing dp array meaning
- Ignoring break after setting dp[i]
public boolean wordBreak(String s, List<String> wordDict) {
boolean[] dp = new boolean[s.length()];
dp[0] = true;
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && wordDict.contains(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}Solution
Step 1: Check dp array size and indexing
The dp array must have length s.length() + 1 to include dp[0] and dp[s.length()] indices.Step 2: Identify impact of incorrect dp size
With size s.length(), dp[s.length()] access causes ArrayIndexOutOfBoundsException.Final Answer:
dp array size should be s.length() + 1 -> Option CQuick Check:
dp size = s.length()+1 fixes index error [OK]
- Setting dp[0] false breaks base case
- Misusing substring indices
- Thinking List vs Set causes error here
["apple", "pen", "applepen", "pine", "pineapple"], which of the following strings can be segmented into dictionary words using the Word Break algorithm?Solution
Step 1: Analyze string "pineapplepenapple" segmentation
It can be segmented as "pine" + "apple" + "pen" + "apple" or "pineapple" + "pen" + "apple" all in dictionary.Step 2: Check other options for invalid segments
The strings in A, B, and C contain substrings like "pens" or "apples" that cannot be segmented using the dictionary words (e.g., A and C end with "pens", B ends with "apples"). Only D can be fully segmented.Final Answer:
"pineapplepenapple" -> Option DQuick Check:
Valid segmentation = "pineapplepenapple" [OK]
- Assuming plural forms are valid
- Ignoring order of words
- Not verifying full segmentation
Ready to prove it?
Pass the test and this pattern moves unknown
