Recursion (Brute Force)
Intuition
Try every possible prefix of the string. If a prefix exists in the dictionary, recursively check whether the remaining suffix can also be segmented. If we reach the end of the string, the segmentation is valid. Without memoization, this explores an exponential number of partitions due to overlapping subproblems.
Algorithm
- If the string is empty, return `true`.
- For each prefix of length 1 to `n`, check if it exists in the dictionary.
- If the prefix is a dictionary word, recursively check the remaining suffix.
- If any recursive call returns `true`, return `true`. Otherwise, return `false`.
O(2^n) in the worst caseSpaceO(n) for the recursion stackCode (C++ · Java · Python · Go)
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> dict(wordDict.begin(), wordDict.end());
return helper(s, dict, 0);
}
bool helper(string& s, unordered_set<string>& dict, int start) {
if (start == s.size()) return true;
for (int end = start + 1; end <= (int)s.size(); end++) {
if (dict.count(s.substr(start, end - start)) && helper(s, dict, end)) {
return true;
}
}
return false;
}
};class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
Set<String> dict = new HashSet<>(wordDict);
return helper(s, dict, 0);
}
private boolean helper(String s, Set<String> dict, int start) {
if (start == s.length()) return true;
for (int end = start + 1; end <= s.length(); end++) {
if (dict.contains(s.substring(start, end)) && helper(s, dict, end)) {
return true;
}
}
return false;
}
}from typing import List
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
word_set = set(wordDict)
def helper(start: int) -> bool:
if start == len(s):
return True
for end in range(start + 1, len(s) + 1):
if s[start:end] in word_set and helper(end):
return True
return False
return helper(0)func wordBreak(s string, wordDict []string) bool {
dict := make(map[string]bool)
for _, w := range wordDict {
dict[w] = true
}
var helper func(start int) bool
helper = func(start int) bool {
if start == len(s) {
return true
}
for end := start + 1; end <= len(s); end++ {
if dict[s[start:end]] && helper(end) {
return true
}
}
return false
}
return helper(0)
}