Given a string s
and a dictionary of strings wordDict
, return true
if s
can be segmented into a space-separated sequence of one or more dictionary words.
Note that the same word in the dictionary may be reused multiple times in the segmentation.
Example 1:
Input: s = "leetcode", wordDict = ["leet","code"] Output: true Explanation: Return true because "leetcode" can be segmented as "leet code".
Example 2:
Input: s = "applepenapple", wordDict = ["apple","pen"] Output: true Explanation: Return true because "applepenapple" can be segmented as "apple pen apple". Note that you are allowed to reuse a dictionary word.
Example 3:
Input: s = "catsandog", wordDict = ["cats","dog","sand","and","cat"] Output: false
Constraints:
1 <= s.length <= 300
1 <= wordDict.length <= 1000
1 <= wordDict[i].length <= 20
s
and wordDict[i]
consist of only lowercase English letters.wordDict
are unique.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to the 'Word Break' problem is like trying every single way to chop up a long string into smaller pieces to see if the pieces are valid words. We're essentially exploring every possible combination of word breaks to find a solution.
Here's how the algorithm would work step-by-step:
def word_break_brute_force(input_string, word_dictionary):
string_length = len(input_string)
# Check if the entire string is a word
if input_string in word_dictionary:
return True
for i in range(1, string_length + 1):
# Consider all possible prefixes of the string
prefix = input_string[:i]
# If current prefix is a valid word
if prefix in word_dictionary:
# Recursively check the remaining string
suffix = input_string[i:]
# See if the rest of the string can also be segmented.
if word_break_brute_force(suffix, word_dictionary):
return True
# If no break combination works, return false
return False
The best way to solve the Word Break problem is to figure out if we can build the target phrase piece by piece using words from our dictionary. We can do this efficiently by remembering if we've already figured out how to build a part of the phrase, preventing redundant work and significantly speeding up the process.
Here's how the algorithm would work step-by-step:
def word_break(phrase, word_dictionary):
phrase_length = len(phrase)
buildable = [False] * (phrase_length + 1)
buildable[0] = True
for i in range(1, phrase_length + 1):
for j in range(i):
# See if we've found a valid word to extend a previous valid break
if buildable[j] and phrase[j:i] in word_dictionary:
buildable[i] = True
break
# If the last element is true, entire phrase is buildable
return buildable[phrase_length]
Case | How to Handle |
---|---|
Empty string s | If s is empty, return true, as an empty string can be considered segmented. |
Empty dictionary wordDict | If the dictionary is empty and s is not empty, return false since no words can be used for segmentation. |
s is a single character, not in wordDict | Return false, since the single character cannot be segmented if it's not a valid word. |
s is a very long string, and wordDict is small | The solution's time complexity should be considered, a dynamic programming approach can prevent exponential time in recursion. |
wordDict contains very long words, longer than s | Longer words can be ignored since they will never match any part of s. |
wordDict contains duplicate words | Duplicate words are treated the same as the original and do not cause incorrect output if a valid segmentation exists. |
s cannot be segmented at all | The algorithm should correctly return false if no combination of words from wordDict can form s. |
s can be segmented in multiple ways | The algorithm only needs to determine if *any* segmentation is possible, the existence of multiple solutions doesn't affect correctness. |