Word Break Problem in DSA Python - 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.
wordDict = set(["apple", "pen", "applepen", "pine", "pineapple"])
s = "pineapplepenapple"
# dp[i] means s[:i] can be segmented
dp = [False] * (len(s) + 1)
dp[0] = True
for i in range(1, len(s) + 1):
for j in range(i):
if dp[j] and s[j:i] in wordDict:
dp[i] = True
break
print(dp[len(s)])
This code checks if the string can be split into words from the dictionary using dynamic programming.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops where for each position i, we check all positions j before i.
- How many times: Outer loop runs n times, inner loop runs up to n times, so roughly 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 input 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 checks.
[X] Wrong: "The solution runs in linear time because it just loops through the string once."
[OK] Correct: The code has nested loops, so it checks many substrings, not just once through the string.
Understanding this time complexity helps you explain how dynamic programming improves over naive recursion and why nested loops matter.
"What if we used a trie data structure for the dictionary lookups? 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 valid words from a dictionary.Step 2: Match the goal with options
To check if a string can be segmented into a sequence of dictionary words correctly describes this goal, while others describe unrelated tasks.Final Answer:
To check if a string can be segmented into a sequence of dictionary words -> Option AQuick Check:
Word Break Problem = Check segmentation [OK]
- Confusing Word Break with string reversal
- Thinking it counts vowels or finds longest word
- Assuming it modifies the string instead of checking segmentation
s[:i] is in a dictionary wordDict inside a loop?Solution
Step 1: Understand Python membership syntax
To check if an element is in a collection, useelement in collection.Step 2: Apply to substring and dictionary
We want to check if substrings[:i]is inwordDict, soif s[:i] in wordDict:is correct.Final Answer:
if s[:i] in wordDict: -> Option BQuick Check:
Membership test uses 'in' keyword [OK]
- Using 'contains' instead of 'in'
- Reversing order of operands in membership test
- Using equality '==' instead of membership
def wordBreak(s, wordDict):
dp = [False] * (len(s) + 1)
dp[0] = True
for i in range(1, len(s) + 1):
for j in range(i):
if dp[j] and s[j:i] in wordDict:
dp[i] = True
break
return dp[-1]
print(wordBreak('applepenapple', {'apple', 'pen'}))Solution
Step 1: Understand the dynamic programming approach
The code uses a list dp where dp[i] is true if s[:i] can be segmented into dictionary words.Step 2: Trace the input 'applepenapple'
'apple' and 'pen' are in the dictionary. The string can be segmented as 'apple' + 'pen' + 'apple', so dp[-1] becomes True.Final Answer:
True -> Option DQuick Check:
String segments into dictionary words = True [OK]
- Assuming false because of nested loops
- Confusing dp indices and substring slicing
- Ignoring the break statement after true found
def wordBreak(s, wordDict):
dp = [False] * len(s)
dp[0] = True
for i in range(1, len(s) + 1):
for j in range(i):
if dp[j] and s[j:i] in wordDict:
dp[i] = True
return dp[-1]Solution
Step 1: Check dp list initialization
dp should have length len(s) + 1 to include dp[0] for empty string and dp[len(s)] for full string.Step 2: Identify impact of incorrect dp size
With dp size len(s), dp[i] access when i == len(s) causes index error or incorrect logic.Final Answer:
dp list size is incorrect; should be len(s) + 1 -> Option AQuick Check:
dp size = len(s)+1 needed for indexing [OK]
- Initializing dp with length len(s) only
- Forgetting dp[0] represents empty string
- Not breaking loop after setting dp[i] true
s = 'catsanddog' and dictionary wordDict = {'cat', 'cats', 'and', 'sand', 'dog'}, which of the following lists contains all possible valid segmentations of s?Solution
Step 1: Identify valid dictionary words in the string
Words 'cat', 'cats', 'and', 'sand', 'dog' are in the dictionary.Step 2: Find segmentations matching dictionary words
Possible splits: 'cats' + 'and' + 'dog' and 'cat' + 'sand' + 'dog' are valid segmentations.Final Answer:
['cats and dog', 'cat sand dog'] -> Option CQuick Check:
All segments are dictionary words [OK]
- Ignoring valid splits and choosing whole string
- Mixing invalid word splits
- Confusing word boundaries
Ready to prove it?
Pass the test and this pattern moves unknown
