Word Break - JS Solution

JS
Editorial

Solution explanation

Solution explanation

Approach

Approach (Dynamic Programming — End-Exclusive Prefixes with Length Bounds Optimization)

We solve the Word Break problem using Dynamic Programming (DP) over end-exclusive prefixes of the input string. Let the input string be s and the dictionary be wordDict. We define a boolean array dp of length m + 1 (where m = s.length) such that:

  • dp[substringExclusiveEndIndex] is true if and only if the substring s[0:substringExclusiveEndIndex] (end is exclusive) can be segmented into valid dictionary words.

Initialization

  • Build a hash set wordSet from wordDict for O(1) average lookup time.
  • Compute the minimum and maximum word lengths in the dictionary:
    minWordLen = min(len(w)) for w ∈ wordDict
    maxWordLen = max(len(w)) for w ∈ wordDict
    This allows us to ignore substrings that are too short or too long to match any valid word.
  • Initialize the boolean array dp with all values set to false.
  • Set the base case dp[0] = true, representing that the empty string can always be segmented.

Iteration Logic

We iterate over all possible end-exclusive indices of the string that could end a valid word:

  • For each substringExclusiveEndIndex from max(1, minWordLen) to m:
    • Restrict the range of possible start indices using the known word length bounds:
      startLowerBound = max(0, substringExclusiveEndIndex - maxWordLen)
      startUpperBound = substringExclusiveEndIndex - minWordLen
    • For each substringStartIndex in [startLowerBound, startUpperBound]: if dp[substringStartIndex] = true (meaning s[0:substringStartIndex], end-exclusive, can be segmented) and s[substringStartIndex:substringExclusiveEndIndex] (end-exclusive) exists in wordSet, we can also segment s[0:substringExclusiveEndIndex] (end-exclusive).
    • Once such a substring is found, we set dp[substringExclusiveEndIndex] = true and skip further checks for this index.

Final Result

After completing all iterations, dp[m] (where m = s.length) represents whether the entire string s can be segmented into valid dictionary words. If dp[m] = true, segmentation is possible; otherwise, it is not.

Time Complexity

Let m = s.length and define rangeLen = maxWordLen - minWordLen + 1 (the word-length range allowed by the dictionary).

For each end index e (from 1 to m), we only test substrings whose lengths lie in [minWordLen, maxWordLen] and do not exceed the available prefix (≤ e). Hence the number of candidates per step is at most min(rangeLen, e), and thus ≤ min(rangeLen, m) overall.

If checking one candidate requires reading/building the substring of length L (cost Θ(L)), then in the worst case L ≤ min(maxWordLen, m). Therefore, the total worst-case time complexity is: O(m × min(rangeLen, m) × min(maxWordLen, m)).

Each dictionary membership check is O(1) on average thanks to the hash set.

Space Complexity

The dynamic programming array dp stores one boolean for each prefix of the string, giving a space cost of O(m), where m = s.length.

The dictionary is stored in a hash set (wordSet), requiring O(n × avgWordLen) space overall, where n is the number of words and avgWordLen is the average word length in the dictionary. This includes both the set structure and the stored word strings.

Hence, the overall auxiliary space complexity is: O(m + n × avgWordLen).

Visucodize editorial solution titled JS Solution for LeetCode's Word Break coding problem. Includes code and may include explanation. You can animate the code step by step using the provided input by clicking the run button, or fork it locally to update the code and input for custom visualization. View the original problem at https://leetcode.com/problems/word-break.