代码随想录训练营第46天|139.单词拆分

139.单词拆分

139.单词拆分

对于单词拆分,题意为,给定的字符串是否可以由字典中的字符串组成。
对此,我们可以用一个dp数组用于记录 截止到ii,是否可以用字典中的字符串表示,例如,s=“abcd”,dict={“a”,“b”,“ab”},dp[1]表示a能否由字典中的元素组成,答案是可以的,因此dp[1]=true。dp[3]为“abc”不能由字典表示,因此,dp[3]=false。
对此,我们从前往后遍历,遍历到某个位置ii时,判断s的前ii个元素能否被表示,利用前面已经判断过的字符串,假如dp[jj]=true,也就是说s[0]-s[jj]已经可以由字典表示,因此,如果此时切片s[jj]-s[ii]如果可以被表示,就令dp[ii]=true。

回溯四部曲
1.dp数组的含义,表示,截止到字符串的某个位置s[ii]能否由字典中的元素表示,可以表示即为true。
2.dp的推导公式,遍历之前已经判断过的元素,如果存在某个位置为true,并且后面的子字符串也在字典中,则更新值为true。

for(int jj =0;jj<ii;jj++)
                {
                    string word = s.substr(jj,ii-jj);
                    if(dp[jj]&&wordSet.find(word)!=wordSet.end())
                        {
                            dp[ii] = true;
                            break;
                        }
                }

3.dp的初始化,我们令dp[0]=true,其他为false,用于表示,dp[0]为true,方便更新新的元素。
4.dp的遍历顺序,我们由前向后进行遍历。

代码

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
        vector<bool> dp(s.size()+1,false);
        dp[0] = true;
        for(int ii =1;ii<s.size()+1;ii++)
        {
            for(int jj =0;jj<ii;jj++)
                {
                    string word = s.substr(jj,ii-jj);
                    if(dp[jj]&&wordSet.find(word)!=wordSet.end())
                        {
                            dp[ii] = true;
                            break;
                        }
                }
        }
        return dp[s.size()];
    }
};

你可能感兴趣的:(算法,动态规划,leetcode)