LeeCode 472 Trie + DP

158 篇文章 1 订阅
题意

传送门 LeeCode 472 连接词

题解

令单词数量为 n n n,单词长度为 m m m d p [ i ] dp[i] dp[i] 代表单词 s s s 从位置 i i i 到结尾处,能否由至少一个较短单词构成,边界条件 d p [ m ] = 1 dp[m]=1 dp[m]=1。可以通过建 T r i e Trie Trie O ( m ) O(m) O(m) 枚举以 s [ i ] s[i] s[i] 为开头的较短单词,记忆化求解。总时间复杂度 O ( n m 2 ) O(nm^2) O(nm2)

class Solution
{
    const int MAXN = 1E3 + 5, MAXS = 1E5 + 5;

public:
    bool dp[MAXN];
    int rt, n, ch[MAXS][26];
    bool end[MAXS];
    int build()
    {
        memset(ch[n], -1, sizeof(ch[n]));
        end[n] = 0;
        return n++;
    }
    void insert(string &s)
    {
        int p = rt, len = s.size();
        for (int i = 0; i < len; ++i)
        {
            int c = s[i] - 'a';
            if (ch[p][c] == -1)
                ch[p][c] = build();
            p = ch[p][c];
        }
        end[p] = 1;
    }
    bool rec(string &s, int k)
    {
        if (k == (int)s.size())
            return 1;
        bool &res = dp[k];
        int p = rt;
        for (int i = k; i < (int)s.size(); ++i)
        {
            int c = s[i] - 'a';
            if (ch[p][c] == -1)
                break;
            p = ch[p][c];
            if (end[p] && rec(s, i + 1))
            {
                res = 1;
                break;
            }
        }
        return res;
    }
    vector<string> findAllConcatenatedWordsInADict(vector<string> &words)
    {
        sort(words.begin(), words.end(), [&](string &a, string &b) -> bool
             { return a.size() < b.size(); });
        n = 0;
        rt = build();
        vector<string> res;
        for (auto &s : words)
        {
            if (s.size() == 0)
                continue;
            memset(dp, 0, sizeof(dp));
            if (rec(s, 0))
                res.push_back(s);
            else
                insert(s);
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值