Medium
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 <= 3001 <= wordDict.length <= 10001 <= wordDict[i].length <= 20s and wordDict[i] consist of only lowercase English letters.wordDict are unique.func wordBreak(s string, wordDict []string) bool {
	if len(wordDict) == 0 {
		return false
	}
	maxL := 0
	minL := len(wordDict[0])
	dict := map[string]bool{}
	for _, w := range wordDict {
		maxL = max(maxL, len(w))
		minL = min(minL, len(w))
		dict[w] = true
	}
	dp := make([]bool, len(s)+1)
	dp[0] = true
	for i := minL; i <= len(s); i++ {
		for j := minL; j <= maxL && i-j >= 0; j++ {
			if dp[i-j] && dict[s[i-j:i]] {
				dp[i] = true
				break
			}
		}
	}
	return dp[len(s)]
}
func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}
func min(a, b int) int {
	if a > b {
		return b
	}
	return a
}