[C++] LeetCode 140. 单词拆分 II

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lv1224/article/details/79973156

题目

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字串中增加空格来构建一个句子,使得句子里所有的单词都在词典中。你可以假设字典中无重复的单词。
返回所有这些可能的句子。
例如,给出
s = "catsanddog",
dict = ["cat", "cats", "and", "sand", "dog"].
答案为 ["cats and dog", "cat sand dog"].
UPDATE (2017/1/4):
wordDict 参数已被更改为字符串列表(而不是一组字符串)。请重新加载代码定义以获取最新更改。

题解

这道题最直观的做法就是直接用递归,DFS得出结果。但是直接采用DFS会导致部分case超时。所以比较常用的方法就是DP+DFS结合。其中用DP得出当前字符串s是否可分,如果不可分直接返回结果。如果可分,再调用DFS得出所有分割的结果。
DP中,flag[i]表示前i个字符是否可分,可分即为true否则为false。则flag[n]即为字符串s是否可分。
技巧:
采用unordered_set代替原来的wordDict,方便快速查找。
记录得到wordDict中最长的字符串的长度maxLen,则DFS中需要考虑的最大长度即为maxLen

代码

class Solution {
public:
    void dfs(string &s,unordered_set<string> &hash,int idx,int maxLen,vector<string> &res,string path,vector<vector<int>> &flag){
        int n=s.size();
        if(idx>=n){
            path.erase(path.begin());
            res.push_back(path);
            return;
        }
        for(int i=0;i<maxLen&&i+idx<n;i++){
            string tmp="";
            if(flag[idx][idx+i]==-1) continue;
            else if(flag[idx][idx+i]==0){
                tmp=s.substr(idx,i+1);
                if(hash.find(tmp)==hash.end()){
                    flag[idx][idx+i]=-1;
                    continue;
                }
                else{
                    flag[idx][idx+i]=1;
                }
            }
            else{
                tmp=s.substr(idx,i+1);
            }
            dfs(s,hash,idx+i+1,maxLen,res,path+" "+tmp,flag);
        }
    }
    bool isBreak(string &s,unordered_set<string> &hash,int maxLen){
        int n=s.size();
        vector<bool> flag(n+1,false);
        flag[0]=true;
        for(int i=1;i<=n;i++){
            for(int j=i;j>0&&i-j+1<=maxLen;j--){        //这里加上i-j+1<=maxLen,可以较大的提高运行效率,减少运行时间
                string tmp=s.substr(j-1,i-j+1);
                if(hash.find(tmp)==hash.end()) continue;
                if(flag[j-1]==true) flag[i]=true;
            }
        }
        return flag[n];
    }
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        int n=s.size();
        vector<string> res;
        string path;
        unordered_set<string> hash;
        vector<vector<int>> flag(n,vector<int>(n,0));
        int maxLen=0;
        for(auto &str:wordDict){
            maxLen=max(maxLen,(int)str.size());
            hash.insert(str);
        }
        if(isBreak(s,hash,maxLen)==false) return res;
        dfs(s,hash,0,maxLen,res,path,flag);
        return res;
    }
};

提交结果

这里写图片描述

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页