# [Word Break](https://leetcode.com/problems/word-break/solution/) ###### tags: `Leetcode`, `Medium`, `Dynamic Programming` ## Approach ![](https://i.imgur.com/rkn0Sj7.png) * Initialize `dp` array to one more than the length of the string, set all the values to `False` and set the last value to `True`. * Iterate backwards in the string * For every word in the dictionary, check the same length of substring from the current index position and check if it matches the word. * If it matches then set the value of `dp[index] = dp[index + len(word)]` * If it does not match with any of the words in the dict, then continue with the for loop and shift index one place to the left * Return `dp[0]` ## Asymptotic Analysis ### Time Complexity: **O(M.N<sup>2</sup>)** ### Space Complexity: **O(M)** M=Length of the string N=Length of the dictionary ## Code ``` python from typing import List class WordBreak: def word_break(self, s: str, word_dict: List[str]) -> bool: dp = [False] * (len(s) + 1) dp[len(s)] = True for index in range(len(s) - 1, -1, -1): for word in word_dict: if (index + len(word) <= len(s) and s[index : index + len(word)] == word): dp[index] = dp[index + len(word)] if dp[index]: break return dp[0] input_string1, input_string2 = 'applepenapple', 'catsandog' word_dict1, word_dict2 = ['apple', 'pen'], ['cats', 'dog', 'sand', 'and', 'cat'] wb = WordBreak() print(f"Can '{input_string1}' be segmented? -> {wb.word_break(input_string1, word_dict1)}") print(f"Can '{input_string2}' be segmented? -> {wb.word_break(input_string2, word_dict2)}") ```