Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Can the string be segmented in JavaScript
The string segmentation problem determines if a given string can be broken down into words that exist in a provided dictionary. This is a classic dynamic programming problem with practical applications in natural language processing and text analysis.
What is String Segmentation?
String segmentation involves breaking a continuous string into meaningful words using a dictionary. For example, given the string "haveapplepie" and dictionary ["have", "apple", "pie"], we can segment it as "have" + "apple" + "pie".
// Example visualization
const dictionary = ["apple", "have", "pie"];
const input = "haveapplepie";
// Can be segmented as: "have" + "apple" + "pie"
console.log("Segmentation possible: true");
Segmentation possible: true
Brute Force Approach
The simplest approach uses recursion to try all possible segmentations:
function canSegment(str, dictionary) {
// Base case: empty string can always be segmented
if (str.length === 0) return true;
// Try all possible first words
for (let i = 1; i <= str.length; i++) {
let firstWord = str.substring(0, i);
let remaining = str.substring(i);
// If first word exists in dictionary and remaining can be segmented
if (dictionary.includes(firstWord) && canSegment(remaining, dictionary)) {
return true;
}
}
return false;
}
const dictionary = ["apple", "have", "pie"];
const testString = "haveapplepie";
console.log(canSegment(testString, dictionary));
true
Optimized Approach with Memoization
The brute force approach has exponential time complexity O(2^n). We can optimize it using memoization to achieve O(n²) complexity:
function canSegmentOptimized(str, dictionary) {
const memo = {};
function helper(start) {
// Base case: reached end of string
if (start === str.length) return true;
// Check memoization
if (memo[start] !== undefined) return memo[start];
// Try all possible words starting from current position
for (let end = start + 1; end <= str.length; end++) {
let word = str.substring(start, end);
if (dictionary.includes(word) && helper(end)) {
memo[start] = true;
return true;
}
}
memo[start] = false;
return false;
}
return helper(0);
}
const dictionary = ["apple", "pen", "applepen"];
const testString = "applepenapple";
console.log("Can segment:", canSegmentOptimized(testString, dictionary));
// Test with different examples
const dictionary2 = ["cats", "dog", "sand", "and", "cat"];
console.log("catsanddogs:", canSegmentOptimized("catsanddog", dictionary2));
Can segment: true catsanddogs: true
Dynamic Programming Approach
An iterative bottom-up approach using dynamic programming:
function canSegmentDP(str, dictionary) {
const n = str.length;
const dp = new Array(n + 1).fill(false);
dp[0] = true; // Empty string can always be segmented
for (let i = 1; i <= n; i++) {
for (let j = 0; j < i; j++) {
let word = str.substring(j, i);
if (dp[j] && dictionary.includes(word)) {
dp[i] = true;
break;
}
}
}
return dp[n];
}
const dictionary = ["leet", "code"];
const testString = "leetcode";
console.log("DP approach result:", canSegmentDP(testString, dictionary));
DP approach result: true
Complexity Analysis
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Brute Force | O(2^n) | O(n) |
| Memoization | O(n²) | O(n) |
| Dynamic Programming | O(n²) | O(n) |
Complete Example
function stringSegmentation(str, dictionary) {
const memo = {};
function canBreak(start) {
if (start === str.length) return true;
if (memo[start] !== undefined) return memo[start];
for (let end = start + 1; end <= str.length; end++) {
let prefix = str.substring(start, end);
if (dictionary.includes(prefix) && canBreak(end)) {
return memo[start] = true;
}
}
return memo[start] = false;
}
return canBreak(0);
}
// Test cases
const testCases = [
{ str: "leetcode", dict: ["leet", "code"] },
{ str: "applepenapple", dict: ["apple", "pen"] },
{ str: "catsanddogs", dict: ["cats", "dog", "sand", "and", "cat"] }
];
testCases.forEach(({ str, dict }, index) => {
console.log(`Test ${index + 1}: "${str}" -> ${stringSegmentation(str, dict)}`);
});
Test 1: "leetcode" -> true Test 2: "applepenapple" -> true Test 3: "catsanddogs" -> false
Conclusion
String segmentation can be solved efficiently using dynamic programming with memoization, reducing complexity from O(2^n) to O(n²). This technique is valuable for word break problems and text processing applications.
