leetcode word break ii

问题描述

给定一个字符串s和一组单词dict,在s中添加空格将s变成一个句子,使得句子中的每一个单词都是dict中的单词
返回所有可能的结果
例如:给定的字符串s =“catsanddog”,
dict =[“cat”, “cats”, “and”, “sand”, “dog”].

返回的结果为[“cats and dog”, “cat sand dog”].

解决方案

将动态规划的状态存到二维数组,在数组上搜索寻找解。


动态规划根本思想是记录状态值:
DP[i][j]:
           j    0       1       2       3       4       5       6  
        i 
        0       c       ca      cat(1)  cats(1) catsa   catsan  catsand
        1               a       at      ats     atsa    atsan   atsand       
        2                       t       ts      tsa     tsan    tsand
        3                               s       sa      san     sand(1)
        4                                       a       an      and(1)
        5                                               n       nd
        6                                                       d
 
DP[i][j]里:
0       c       ca      cat(1)  cats(1) catsa   catsan  catsand
1       a       at      ats     atsa    atsan   atsand
2       t       ts      tsa     tsan    tsand
3       s       sa      san     sand(1)
4       a       an      and(1)
5       n       nd
6       d
思路:
DP[i][j]存放着字符串s的所有子字符串在dict中的状态值。
遍历顺序是先搜索i到串尾的子串,若子串在dict里,再搜索串头到i的子串。
        c a t s a n d
        j     i
比如,dp[3][3]=1表明"sand"在dict里,再搜索cat......
再搜索顺序为cat at t......
 
 
output(6,s):
i=6     k:0 1 2 3 4 5 6
dp[k][i-k]:偏移为k,截断字符串长度i-k+1
沿着次对角线遍历,相当于从头部每隔一个字符截断!!!
dp[0][6]:偏移为0,截断字符串长度7      0
dp[1][5]:偏移为1,截断字符串长度6      0
dp[2][4]:偏移为2,截断字符串长度5      0
dp[3][3]:偏移为3,截断字符串长度4      1   -->output(2,s)
dp[4][2]:偏移为4,截断字符串长度3      1   -->output(3,s)
dp[5][1]:偏移为5,截断字符串长度2      0
dp[6][0]:偏移为6,截断字符串长度1      0
 
output(2,s):
i=2     k:0 1 2
dp[k][i-k]:偏移为k,截断字符串长度i-k+1
沿着次对角线遍历,相当于从头部每隔一个字符截断!!!
dp[0][2]:偏移为0,截断字符串长度3      1   -->output(-1,s)
dp[1][1]:偏移为1,截断字符串长度2      0
dp[2][0]:偏移为2,截断字符串长度1      0
 
output(-1,s):
......
 
 
mystring.push_back(s.substr(k,i-k+1));
output(k-1,s);
s.substr(k,i-k+1)==>递归output(k-1,s)!!!
偏移为k,截断长度i-(k-1);                           ------
==>递归为k-1                                              |--->处理字符串长度i 
从偏移为0,截断长度k开始以次对角线方向遍历!!!       ------
 
class Solution {
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        //构造dp数组
        int len = s.size();
        dp = new vector<bool>[len];
        for(int i = 0;i<len;i++){
            for(int j = i;j<len;j++){
                dp[i].push_back(match(s.substr(i,j-i+1),dict));
            }
        }
        output(len-1,s);
        return result;
    }
    bool match(string s,unordered_set<string> &dict){
        if(dict.find(s)==dict.end())return false;
        else return true;
    }
    void output(int i,string s){
        
        if(i==-1){
            int len_tmp = tmp_result.size();
            string res=tmp_result[len_tmp-1];
            for(int j = len_tmp-2;j>=0;j--){
                res+=' ';
                res+=tmp_result[j];
            }
            result.push_back(res);
        }
        else{
            for(int j=i;j>=0;j--){
                if(dp[j][i-j]){
                    tmp_result.push_back(s.substr(j,i-j+1));
                    output(j-1,s);
                    tmp_result.pop_back();
                }
            }
        }
    }
    vector<string> result;
    vector<string> tmp_result;
    vector<bool> *dp;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值