THN Interview Prep

139. Word Break

At a Glance

  • Topic: Array
  • Pattern: Analyze Pattern
  • Difficulty: Medium
  • LeetCode: 139

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.

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 wordD...

Approach & Solution Steps

  • Brute force — try all splits — exponential.
  • Better — BFS/DFS with memo on start index — O(n^3) worst with substring checks, O(n * m) with clever hashing.
  • Optimalreachable[end] boolean DP — O(n^2 * average_word_check) time; with trie can prune. <- pick this in interview.

Optimal JS Solution

function wordBreakTable(s, wordDict) {
	const length = s.length;
	const wordSet = new Set(wordDict);
	const reachable = new Array(length + 1).fill(false);
	reachable[0] = true;
	for (let end = 1; end <= length; end++) {
		for (let start = 0; start < end; start++) {
			if (!reachable[start]) continue;
			const segment = s.slice(start, end);
			if (wordSet.has(segment)) {
				reachable[end] = true;
				break;
			}
		}
	}
	return reachable[length];
}

function wordBreak(s, wordDict) {
	const length = s.length;
	const wordSet = new Set(wordDict);
	let maxWord = 0;
	for (const word of wordDict) {
		maxWord = Math.max(maxWord, word.length);
	}
	const reachable = new Array(length + 1).fill(false);
	reachable[0] = true;
	for (let start = 0; start < length; start++) {
		if (!reachable[start]) continue;
		const limit = Math.min(length, start + maxWord);
		for (let end = start + 1; end <= limit; end++) {
			const segment = s.slice(start, end);
			if (wordSet.has(segment)) {
				reachable[end] = true;
			}
		}
	}
	return reachable[length];
}

Edge Cases & Pitfalls

  • Always consider empty or null inputs.
  • Watch out for off-by-one index errors.

Mark this page when you finish learning it.

Last updated on

Spotted something unclear or wrong on this page?

On this page