LeetCode题解:Word Break I and II

Word Break


Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

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

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

Word Break II


Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.

Return all such possible sentences.

For example, given
s = "catsanddog",
dict = ["cat", "cats", "and", "sand", "dog"].

A solution is ["cats and dog", "cat sand dog"].

思路:

思路很简单,首先考察字典里的单词的长度,据此截取字符串前端的子串与字典进行比较。如果符合,就从此处截断,继续考察后面字符串即可。

第一题有一个比较恶心的例子,也就是一个有很长的"aaaaaaaa"后面跟着一个“b",偏偏字典里是{"a", "aa", "aaa", "aaaa"}。如果从前分割字符串就会超时,倒是从后面分割就可以迅速发现这个问题。

第二题是第一题的变种,无非是从找到一个解即结束改为搜索整个解空间而已。

题解:

class Solution {
public:
    int min_word_length;
    int max_word_length;
    
    bool testWordBreak(const string& s, const unordered_set<string>& dict)
    {
        const int LEN_S = s.size();
        
        if (s.size() == 0 || dict.find(s) != dict.end())
            return true;    // already part of the dict
        
        
        for(int i = min_word_length; i <= min(max_word_length, LEN_S); ++i)
            if (dict.find(s.substr(LEN_S - i)) != dict.end() && 
                    testWordBreak(s.substr(0, LEN_S - i), dict))
                return true;

        // cannot make a match
        return false;
    }

    bool wordBreak(string s, unordered_set<string> &dict) {
        
        max_word_length = 0;
        min_word_length = 99999; // very large integer
        for(auto& d : dict)
            max_word_length = max(max_word_length, int(d.size())),
            min_word_length = min(min_word_length, int(d.size()));
        
        return testWordBreak(s, dict);
    }
};
class Solution {
public:
    int max_word_length;
    int min_word_length;
    vector<string> current_breaks;
    vector<string> generated_sentence;
    
    void generate_sentence()
    {
        string s = current_breaks.back();
        for(int i = int(current_breaks.size()) - 2; i >= 0; --i)
            s += string(" ") + current_breaks[i];
        generated_sentence.push_back(s);
    }
    
    void testWordBreak(const string& s, const unordered_set<string>& dict)
    {
        const int LEN_S = s.size();
        
        if (LEN_S == 0)
        {
            generate_sentence();
            return;
        }

        for(int i = min_word_length; i <= min(max_word_length, LEN_S); ++i)
        {
            string substr = s.substr(LEN_S - i);
            if (dict.find(substr) != dict.end())
            {
                current_breaks.push_back(substr);
                testWordBreak(s.substr(0, LEN_S - i), dict);
                current_breaks.pop_back();
            }
        }
    }


    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        generated_sentence.clear();
        
        max_word_length = 0;
        min_word_length = 99999; // very large integer
        for(auto& d : dict)
            max_word_length = max(max_word_length, int(d.size())),
            min_word_length = min(min_word_length, int(d.size()));
            
        testWordBreak(s, dict);
        return generated_sentence;
    }
};




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值