Leetcode 139. 单词拆分 C++

题目描述:

给定一个非空字符串 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

分析:

说实话,我自己是没有想出来这道题要用到动态规划的思想,而且一开始也没有理解这种方法。

具体方法:

(1)本题的子问题设为从字符串 s 的前 i 个元素中能否切分出字典 wordDict 里面的单词。因为考虑到空字符串的问题,我们将用于记录子问题信息的vector定义为 len+1 大小。我们认为空字符也包含在了字典中,所以空字符串对应的isWordBreak[0] = true。

(2)为了方便查找某一段字符串是否在字典中,先将字典中的元素保存到一个set类型中。

(3)用一个双循环进行判断。每次判断的是 i 前面的元素。每次判断第 j 个元素到第 i -1个元素是否在字典中。一开始isWordBreak[0]=true,第一个判断语句不起作用,所以是从字符串的第一个元素开始截取字符串判断,一直到找到从字符串第一个元素开始的一段字符串是属于字典中的为止,此时将这个位置 i 的信息记为 true 。

之后的循环,通过程序中第一个判断语句实现每次都从已经找到的字符串的下一个位置开始截取(因为这个题目中,字符串 s 不允许有剩余,所以要这样做)。最后一次判断的是从某一位置一直到末尾的最后一段字符串是否在字典中。

如果最后这一段也在字典中,那么就说明可以实现,否则不可以。

(4)给一个特例,希望有助于理解:

如果字符串从第一元素开始,一直到字符串末尾都不可以截取属于字典中的单次,那么程序外层循环将一直执行到 i = len,isWordBreak[len]=false.那么就直接返回 false。

这段程序的思想:(理解的关键)

从第一元素开始寻找属于字典中的单词,之后在从这个单词的后一个位置继续寻找,如果一直到末尾都是属于字典的,那么就返回true,否则返回false。

解答:

class Solution {
public:
    bool wordBreak(string s, vector& wordDict) {
        int len=s.size();
        vector isWordBreak(len+1,false);//定义一个含有len+1个元素的vector,用于存储子问题信息
        isWordBreak[0]=true;//将第一个元素设置为true,表示当字符串为空的时候也成立
        set dict;
        
        for(const auto &ss:wordDict) dict.insert(ss);
        
        for(int i=0;i

参考:http://www.goodtecher.com/zh/leetcode-139-word-break-%E5%8D%95%E8%AF%8D%E6%8B%86%E5%88%86/

你可能感兴趣的:(leetcode)