Leetcode_word-break-ii

本文介绍LeetCode单词拆分II问题的解决方法,利用动态规划判断字符串是否能由字典中的单词组成,并通过深度优先搜索找出所有可能的组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

地址:http://oj.leetcode.com/problems/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"].

思路:跟上一题类似( http://blog.youkuaiyun.com/flyupliu/article/details/22999485) 刚开始直接dfs又TLE了。所以这是整体的想法是先用动态规划判断能否划分,能划分的话再dfs确定所有的划分方案。有几点需要注意:

1. solution里的vector<string>里肯定没有逗号的,只要把string push 到vector里就好,逗号只是leecode的一种表示方式。因为笔者经常WA,表示wa的case时候,如果是一些树啊链表啊等复杂的数据结构时都是通过数组来意思一下的。

2. dfs确定解法一般都有个回溯的过程,可以计算好要pop()的字符个数,又因为涉及到空格,所以较麻烦,所以用copystr代替,同一个dfs中每次又dfs搜索开始都用同一个copystr。

参考代码, 60ms

class Solution {
public:
    void dfs(vector<string>&res, string tmpstr, map<char, vector<string>>&dm, string s)
    {
        if(s.empty())
        {
            res.push_back(tmpstr);
            return;
        }
        auto it = dm.find(s[0]);
        if(it == dm.end())
            return;
        int len;
        string copystr;
        for(auto str_it = it->second.begin(); str_it != it->second.end(); ++str_it)
        {
            len = (*str_it).length();
            copystr = tmpstr;
            if(len<=s.length() && *str_it==s.substr(0,len))
            {
                if(copystr.empty())
                    copystr+=*str_it;
                else
                {
                    copystr+=' ';
                    copystr+=*str_it;
                }
                dfs(res, copystr, dm, s.substr(len));
            }
        }
    }
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        vector<string>res;
        if(dict.empty() || s.empty())
            return res;
        vector<bool>dp(s.length()+1, false);
        dp[0]=true;
        for(int i = 0; i<s.length(); ++i)
        {
            for(int j = 1; i+j<=s.length(); ++j)
            {
                if(dp[i] && dict.find(s.substr(i,j)) != dict.end())
                    dp[i+j] = true;
            }
        }
        if(!dp[s.length()])
            return res;
        map<char, vector<string>>dm;
        for(auto it = dict.begin(); it!=dict.end(); ++it)
            dm[(*it)[0]].push_back(*it);
        dfs(res, "", dm, s);
        return res;
    }
};

Second trail

class Solution {
private:
    void dfs(vector<string>&ans, vector<string>&vec, string s, unordered_set<string> &dict) {
        if(s.empty()) {
            string str = vec[0];
            for(int i = 1; i<vec.size(); ++i) {
                str += " ";
                str += vec[i];
            }
            ans.push_back(str);
        }
        string word;
        for(int i = 1; i<=s.length(); ++i) {
            word = s.substr(0, i);
            if(dict.find(word)!=dict.end()) {
                vec.push_back(word);
                dfs(ans, vec, s.substr(i), dict);
                vec.pop_back();
            }
        }
    }
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        vector<string>ans, vec;
        if(s.empty() || dict.empty())
            return ans;
        vector<bool>dp(s.length()+1, false);
        dp[0] = true;
        int len;
        for(int i = 0; i<s.length(); ++i){
            for(auto it = dict.begin(); it != dict.end(); ++it) {
                len = (*it).length();
                if(dp[i] && i+len<=s.length() && s.substr(i, len)==*it)
                    dp[i+len] = true;
            }
            if(dp[s.length()])
                break;
        }
        if(dp[s.length()])
            dfs(ans, vec, s, dict);
        return ans;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值