Problem Statement:
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.
Example 1:
Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: "leetcode" can be segmented as "leet code".
Example 2:
Input: s = "applepenapple", wordDict = ["apple", "pen"]
Output: true
Explanation: "applepenapple" can be segmented as "apple pen apple".
Example 3:
Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false
Optimal Approach:
The most efficient approach to solving this problem is Dynamic Programming (DP). We use a boolean DP array where dp[i] is true if s[0...i-1] can be segmented using words from wordDict.
Steps:
- Create a DP array
dpof sizen + 1(wheren = s.length()), initialized tofalse. - Set
dp[0] = true, meaning an empty string can always be segmented. - Iterate through the string and check all possible substrings against
wordDict. - If
dp[j]istrueands[j...i]is inwordDict, setdp[i] = true.
C++ Solution:
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
vector<bool> dp(s.length() + 1, false);
dp[0] = true;
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && wordSet.find(s.substr(j, i - j)) != wordSet.end()) {
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}
};
Step-by-Step Explanation:
- Convert
wordDictinto an unordered set for O(1) lookup time. - Initialize the DP array where
dp[0] = true(empty string case). - Iterate through the string, checking all substrings
s[j...i]. - If
dp[j]istrueands[j...i]exists inwordDict, setdp[i] = true. - Return
dp[s.length()], which tells whetherscan be segmented.
Dry Run Example:
Input:
s = "applepenapple";
wordDict = ["apple", "pen"];
Execution:
| Index (i) | Substring Checked | dp[i] |
|---|---|---|
| 5 | "apple" | true |
| 8 | "pen" | true |
| 13 | "apple" | true |
Output: true
Alternative Approaches:
1. Brute Force (Backtracking):
- Try all possible partitions.
- Time Complexity: O(2^n) (Exponential)
- Space Complexity: O(n) (Recursion Depth)
2. BFS (Graph-based Solution):
- Treat the problem as a graph where nodes represent valid partitions.
- Time Complexity: O(n^2) in worst case.
- Space Complexity: O(n)
Best Solution & Why:
| Approach | Time Complexity | Space Complexity | Why? |
|---|---|---|---|
| Brute Force | O(2^n) | O(n) | Too slow for large inputs |
| BFS | O(n^2) | O(n) | Uses queue, not optimal |
| DP | O(n^2) | O(n) | Best balance of time and space |
Complexity Analysis of DP Solution:
- Time Complexity: O(n^2) → Two nested loops iterating over substrings.
- Space Complexity: O(n) → DP array storing
n+1boolean values.
Conclusion:
- DP is the best approach as it efficiently checks all partitions with O(n^2) complexity.
- Similar Problems for Practice:
Word Break IIConcatenated WordsLongest Word in Dictionary

No comments:
Post a Comment