单词拆分

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

说明:

  • 拆分时可以重复使用字典中的单词。
  • 你可以假设字典中没有重复的单词。

示例1

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。

示例2

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
注意你可以重复使用字典中的单词。

示例3

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

该问题采用动态规划解法。考虑将原问题拆解为两个子问题,以"leetcode"为例,原问题为s,拆分成的两个子问题为"leet",为"code",如果和都有解,那么原问题s也有解,s还可以拆分成"lee"和"tcode",在拆分成的这么多子问题中,只要任意一组子问题有解,那么s就有解。

直接采用暴力拆解会重复计算很多子问题,如计算"lee"和"leet"的子问题。因此采用动态规划避免重复求解子问题。求解时,先初始化长度为s.length()+1的dp数组,当字符串为空时,默认为有解,因此dp[0]true,其它的都先初始化为false。假设当前求解的字符串长度为i,字符串的分割点为j,即字符串被分成s(0,j)s(j+1,i)两个部分,s(0,j)即为dp[j],在之前的结果中可以直接取到,因此只需要再求wordDict中是否包含s(j+1,i)。当dp[j]true并且wordDict包含s(j+1,i)时,dp[i]true。从这个计算过程也可以明显看出,在求解过程中省去了重复计算子问题s(0,j)

class Solution {
public:
    bool wordBreak(string s, vector& wordDict) {
       vector dp;
        dp.push_back(true);
        for(int i=1;i<=s.size();i++) dp.push_back(false);
        for(int i=1;i<=s.size();i++){
            for(int j=0;j

你可能感兴趣的:(单词拆分)