LeetCode Word Break II

Word Break II

  Total Accepted: 7703  Total Submissions: 50334 My Submissions

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"].


写了整整2天!

一直没有碰上过5星的题,碰上了才知道厉害T。T。

dp直接记录下i能够到达的j,且要求J能够到达字符串末端,否则不记录j。虽然它依旧是淳朴的dp+dfs,可是上面那个记录,让它的复杂度噌噌噌降到了O(N^2)* O (dp)!人生如此美好


预处理:tbl[i]事先记录能够到达的位置j。深搜中会多次比较(i, j) 字符串是否属于字典,所以预先处理、记录可以节省很多时间。

class Solution {
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        vector<string> ans;
        vector<vector<int> > tbl = dp(s, dict);
        dfs(0, s.length(), "", ans, s, dict, tbl);
        return ans;
    }
    
    vector<vector<int> > dp(string s, unordered_set<string> dict) {
        int len = s.length();
        vector<vector<int> > tbl(len);
        
        //both i and j infer index
        //from i to len - 1, is it a word?
        for (int i = 0; i < len; i++) {
            if (dict.find(s.substr(i)) != dict.end()) {
                tbl[i].push_back(len - 1);
            }
        }
        //from j to i, is it a word? can it extends to len - 1?
        for (int i = len - 2; i >= 0; i--) {
            if (tbl[i + 1].empty())
                continue;
            for (int j = i; j >= 0; j--) {
                if (dict.find(s.substr(j, i - j + 1)) != dict.end()) {
                    tbl[j].push_back(i);
                }
            }
        }
        return tbl;
    }
    
    void dfs(int st, int len, string cur, vector<string> &ans, string s, unordered_set<string> &dict, vector<vector<int> > &tbl) {
        if (st == len) {
            ans.push_back(cur);
            return;
        }
        //candidate
        vector<int> can = tbl[st];
        int size = can.size();
        for (int i = 0; i < size; i++) {
            string tmp = cur;
            if (tmp != "")
                tmp += " ";
            tmp += s.substr(st, can[i] - st + 1);
            dfs(can[i] + 1, len, tmp, ans, s, dict, tbl);
        }
    }
};



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值