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.


Test Cases

Input:

(String)    s = "leetcode"
(String[])  wordDict = ["leet","code"]

Output:

(boolean) true

Input:

(String)    s = "applepenapple"
(String[])  wordDict = ["apple","pen"]

Output:

(boolean) true

Explanation

Return true because "applepenapple" can be segmented as "apple pen apple". Note that you are allowed to reuse a dictionary word.

Input:

(String)    s = "catsandog"
(String[])  wordDict = ["cats","dog","sand","and","cat"]

Output:

(boolean) false

Solution

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        int n = s.length();
        vector<bool> dp(n, false);
        for(int i=0; i<n; i++) {
            for(int j=0; j<=i; j++) {
                string sub = s.substr(j, i-j+1);
                if (contains(wordDict, sub) && (j==0 || dp[j-1])) {
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[n-1];
    }

    bool contains(vector<string> &v, string s) {
        return find(v.begin(), v.end(), s) != v.end();
    }
};
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        if (s == null || s.length() == 0) return false;

        int n = s.length();
        Set<String> dict = new HashSet<>(wordDict);
        // dp[i] represents whether s[0...i] can be formed by dict
        boolean[] dp = new boolean[n];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j <= i; j++) {
                String sub = s.substring(j, i + 1);

                if (dict.contains(sub) && (j == 0 || dp[j - 1])) {
                    dp[i] = true;
                    break;
                }
            }
        }

        return dp[n - 1];
    }
}
class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        n = len(s)
        dp, st = [False]*n, set(wordDict)
        for i in range(n):
            for j in range(i+1):
                if s[j:i+1] in st and (j==0 or dp[j-1]):
                    dp[i] = True
                    break
        return dp[n-1]
Time Complexity: O(n2)
Space Complexity: O(n)