139. Word Break

来源:互联网 发布:cf手游刷枪刷钻石软件 编辑:程序博客网 时间:2024/06/06 16:57

Description:

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. You may assume the dictionary does not contain duplicate words.

For example, given
s = "leetcode",
dict = ["leet", "code"].

Return true because "leetcode" can be segmented as "leet code".

UPDATE (2017/1/4):
The wordDict parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.


简要题解:

采用动态规划。

子问题i:字符串中从第0个元素(为空)到第i个元素的子串。

每个子问题维护一个值: 是否可以将该子串分割为一个或多个字典单词的空格分隔序列(初始时,全假定为false)。对于第一个子问题,其对应的值c(0)=true。

c(i)与c(i-1)的关系: 在进行c(i)时,首先先确认c(i-1)是否为true。如果不是,则跳过该子问题。否则,一一确认字典dict中以目标字符串s的第i个元素为开头的单词是否与以第i个元素为开头的原字符串中的某个子串相等,如果是的话,假定该子串的长度为len,则有c(i - 1 + len) = true。如果不是,不做任何处理。(初始化时每个子问题都假定为false,在迭代过程中,如果某一个子问题都没有被赋予过true的话,那false就自动是它最终的值)

从i = 1开始,一直迭代下去,直至子问题成为该问题本身。则,该子问题维护的那个真假值就是所要求的。(某些情况下也可以提前终止,如在处理第i个子问题时,c(i - 1 + len) = true刚好为原问题本身,则可直接返回true。不过在这里,我没有实现。因为性能并没有得到明显的提升


代码:

class Solution {public:    bool wordBreak(string s, vector<string>& wordDict) {        vector<bool> dp(s.size() + 1, false);        int sz;        dp[0] = true;        for (int i = 1; i <= s.size(); i++) {            if (!dp[i-1])                continue;                        for (int j = 0; j < wordDict.size(); j++) {                sz = wordDict[j].size();                if (i - 1 + sz > s.size())                    continue;                                if (s.substr(i - 1, sz) == wordDict[j]) {                    dp[i-1+sz] = true;                    cout << wordDict[j] << endl;                }            }        }                return dp[s.size()];    }};