The Problem

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: The same word in the dictionary may be reused multiple times in the segmentation.

For example, given s = "leetcode" and wordDict = ["leet", "code"], return true because "leetcode" can be segmented as "leet code".

Interactive Visualization

Speed:
String Segmentation
Position i: โ€”
Checking: โ€”
Dictionary
Status
Press Step or Play to begin.
Code
fun wordBreak(s: String, wordDict: Set<String>): Boolean {    val n = s.length    val dp = BooleanArray(n + 1)    dp[0] = true  // empty string    for (i in 1..n) {        for (j in 0 until i) {            if (dp[j] && s.substring(j, i) in wordDict) {                dp[i] = true                break            }        }    }    return dp[n]}

How It Works

Key Insight

The Word Break problem uses dynamic programming to build up a solution from smaller subproblems. We define dp[i] as true if the substring s[0:i] (first i characters) can be segmented into dictionary words.

The Algorithm

  • Base case: dp[0] = True โ€” an empty string can always be segmented.
  • For each position i from 1 to n: Check all possible split points j where 0 โ‰ค j < i.
  • Check if valid split: If dp[j] is true (meaning s[0:j] can be segmented) AND s[j:i] is in the dictionary, then dp[i] = True.
  • Return: dp[n] tells us if the entire string can be segmented.

Recurrence Relation

dp[i] = dp[j] AND (s[j:i] in wordDict) for any j in [0, i)

Complexity

Time O(nยฒ ร— m)
Space O(n)

Where n is the length of the string and m is the average cost of dictionary lookup. With a hash set for the dictionary, m is O(1) on average, giving O(nยฒ) time. We use O(n) space for the dp array. The nested loops check all possible substrings, leading to O(nยฒ) substring checks.