1、题目描述
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine 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.
- You may assume the dictionary does not contain duplicate words.
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
2、问题描述:
- 判断一个字符数组是否可以切分成字典里的单词。
3、问题关键:
- 1.动态规划题。
- 2.建立一个hash表, 存放单词,然后在str中找看是否包含所有的单词。
一个合理的划分,j 到i是一个划分,那么0到j - 1也必须是一个合理的划分。所以状态转移是f[i] == true && f[j - 1] == true;
实际操作的时候,这个地方为什么是f[j]呢,不是j - 1,是因为我们从i = 1开始的,这是一个前开后闭的区间。否则,s.substr(j, i - j + 1),这样主要是为了避免边界条件。见下面程序。
f[i] = t.count(s.substr(j, i - j)) && f[j]
/*
初始化:f[0] = true;
状态表示:f[i] 表示前i个字母,是否存在一种合法的划分方案。
状态转移:f[i] = true 当且仅当,存在某个j,使得s[j….i] in wordDict 且 f[j – 1] = true;
*/
4、C++代码:
/*
初始化:f[0] = true;
状态表示:f[i] 表示前i个字母,是否存在一种合法的划分方案。
状态转移:f[i] = true 当且仅当,存在某个j,使得s[j....i] in wordDict 且 f[j - 1] = true;
*/
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> t;
for (auto word : wordDict) t.insert(word);
int n = s.size();
vector<bool> f(n + 1, false);
f[0] = true;
for (int i = 0; i <= n; i ++)
for (int j = 0; j < i; j ++ )
if (t.count(s.substr(j, i - j)) && f[j] ) {//这个地方为什么是j呢,不是j - 1,是因为我们从i = 1开始的,这是一个前开后闭的区间。否则,s.substr(j, i - j + 1),这样主要是为了避免边界条件。
f[i] = true;
break;
}
return f[n] ;
}
};