[LeetCode OJ] Word Break II 解题报告

题目地址:https://oj.leetcode.com/problems/word-break-ii/

题意:给一个字典和一个字符串,用字典将字符串中的单词全部提取出来,返回所有可行的结果

解题思路:dp+针对特殊case的处理,这里二维dp[i][j](i表示从第i个字符开始,j表示字符串的长度)表示子串s是否在字典内,最后dfs出答案既可。

特殊case:

Input: 

“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab”, [“a”,”aa”,”aaa”,”aaaa”,”aaaaa”,”aaaaaa”,”aaaaaaa”,”aaaaaaaa”,”aaaaaaaaa”,”aaaaaaaaaa”] 

对于这个case,如果dfs枚举答案时从前往后枚举的话就会超时,所以我就从后往前枚举了。

要点:复习了dp的概念,有时间的话再去复习下揹包九讲,毕竟很久没碰过dp了。

#include<unordered_set>
using namespace std;
class Solution {
    vector<bool> *dp;
    vector<string> matchStr;
    vector<string> ans;
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        int len = s.size();
        dp = new vector<bool>[len];
        for(int i=0; i<len; ++i){
            for(int j=i; j<len; ++j){
                string str = s.substr(i,j-i+1);
                dp[i].push_back(match(str,dict));
            }
        }
        checkAns(len-1,s);
        return ans;
    }

    bool match(string& s1,unordered_set<string> &dict){
        if(dict.find(s1)==dict.end()){
            return 0;
        }
        else{
            return 1;
        }
    }

    void checkAns(int endPos,string& s){
        if(endPos == -1){
            getAns();
            return;
        }
        for(int len = 0; len<endPos+1; ++len){
            if(dp[len][endPos-len]){
                matchStr.push_back(s.substr(len,endPos-len+1));
                checkAns(len-1,s);
                matchStr.pop_back();
            }
        }
    }

    void getAns(){
        string str;
        int size = matchStr.size();
        for(int i=size-1; i>=0;--i){
            str += matchStr[i];
            if(i != 0){
                str += " ";
            }
        }
        ans.push_back(str);
    }
};
点赞