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<string>& wordDict) {
        int len=s.size();
        vector<bool> isWordBreak(len+1,false);//定义一个含有len+1个元素的vector,用于存储子问题信息
        isWordBreak[0]=true;//将第一个元素设置为true,表示当字符串为空的时候也成立
        set<string> dict;
        
        for(const auto &ss:wordDict) dict.insert(ss);
        
        for(int i=0;i<len+1;++i)
        {
            for(int j=0;j<i;++j)
            {
                if(!isWordBreak[j])//本条语句用于控制,每次都从上一次找到的元素的下一个位置开始截取字符串
                    continue;
                if(dict.find(s.substr(j,i-j))!=dict.end())//从位置j开始,截取i-j长度的字符串,如果没有找到,那么将返回最后一个元素的后一个位置的迭代器
                {
                    isWordBreak[i]=true;
                    break;
                }
            }
        }
        return isWordBreak[len];
    }
};

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

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值