• 139. 单词拆分 与 140. 单词拆分 II


    139. 单词拆分

    给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s

    注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

    示例 1:

    输入: s = "leetcode", wordDict = ["leet", "code"]
    输出: true
    解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
    

    示例 2:

    输入: s = "applepenapple", wordDict = ["apple", "pen"]
    输出: true
    解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
         注意,你可以重复使用字典中的单词。
    

    示例 3:

    输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
    输出: false
    

    提示:

    • 1 <= s.length <= 300
    • 1 <= wordDict.length <= 1000
    • 1 <= wordDict[i].length <= 20
    • swordDict[i] 仅有小写英文字母组成
    • wordDict 中的所有字符串 互不相同
    • 解析: 多重背包就是
    • 背包重量为s总长度,每个单词的重量为自己的长度,价值也为自己的长度,当装满时价值最高,最高为s长度

    话说注意:

    01背包和多重背包写法

    class Solution {
    public:
    
        bool wordBreak(string s, vector<string>& wordDict) {
            int dp[310];
            memset(dp, 0, sizeof(dp));
            // for(int i = 0; i < wordDict.size(); i++)
            // {
            //     int m = wordDict[i].size();
            //     for(int j = s.length() - 1; j >= m - 1; j--)
            //     {
            //         int k = j;
            //         while(k >= j - m + 1)
            //         {
            //             if(s[k] != wordDict[i][m - 1 - (j - k)])
            //                 break;
            //             k--;
            //         }
            //         if(k >= j - m + 1) continue;
            //         if(j - m < 0) dp[j] = max(dp[j], m);
            //         else dp[j] = max(dp[j], dp[j - m] + m);
            //         cout << j << "  " << dp[j] << endl;
            //     }
            // }
    
            for(int j = 0; j < s.length(); j++)
            {
                for(int i = 0; i < wordDict.size(); i++)
                {
                    int m = wordDict[i].size();
                    if(j - m + 1 >= 0)
                    {
                        int k = j;
                        while(k >= j - m + 1)
                        {
                            if(s[k] != wordDict[i][m - 1 - (j - k)])
                                break;
                            k--;
                        }
                        if(k >= j - m + 1) continue;
                        if(j - m < 0) dp[j] = max(dp[j], m);
                        else dp[j] = max(dp[j], dp[j - m] + m);
                    }
    
                }
    
    
            }
    
    
    
    
            // cout << dp[s.length() - 1] << endl;
            return dp[s.length() - 1] == s.length();
    
    
    
        }
    };

    单词拆分II

    140. 单词拆分 II

    给定一个字符串 s 和一个字符串字典 wordDict ,在字符串 s 中增加空格来构建一个句子,使得句子中所有的单词都在词典中。以任意顺序 返回所有这些可能的句子。

    注意:词典中的同一个单词可能在分段中被重复使用多次。

    示例 1:

    输入:s = "catsanddog", wordDict = ["cat","cats","and","sand","dog"]
    输出:["cats and dog","cat sand dog"]
    

    示例 2:

    输入:s = "pineapplepenapple", wordDict = ["apple","pen","applepen","pine","pineapple"]
    输出:["pine apple pen apple","pineapple pen apple","pine applepen apple"]
    解释: 注意你可以重复使用字典中的单词。
    

    示例 3:

    输入:s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
    输出:[]
    

    提示:

    • 1 <= s.length <= 20
    • 1 <= wordDict.length <= 1000
    • 1 <= wordDict[i].length <= 10
    • s 和 wordDict[i] 仅有小写英文字母组成
    • wordDict 中所有字符串都 不同

    我用的字典树,一年前写的题

    不知道unordered_map可不可以过

    class Solution {
    public:
        int tree[10010][26];
        bool vis[10010];
        int cnt;
        vector<string> v;
        void build(string str)
        {
            int len = str.length();
            int rt = 0;
            for(int i = 0; i < len; i++)
            {
                int x = str[i] - 'a';
                if(tree[rt][x] == 0)
                {
                    tree[rt][x] = ++cnt;
                }
                rt =  tree[rt][x];
            }
            vis[rt] = 1;
        }
        void dfs(string s, int k, string str)
        {
            if(k >= s.length())
            {
                v.push_back(str);
                return;
            }
            int rt = 0;
            int len = s.length();
            string tmp = "";
            while(k < len)
            {
                int x = s[k] - 'a';
                rt = tree[rt][x];
                if(rt == 0) break;
                tmp += s[k];
                if(vis[rt])
                    dfs(s, k + 1, str == "" ? str + tmp : str + " " + tmp);
                k++;
    
            }
        }
    
    
    
        vector<string> wordBreak(string s, vector<string>& wordDict) {
            cnt = 0;
            memset(vis, 0, sizeof(vis));
            memset(tree, 0, sizeof(tree));
            int len = wordDict.size();
            for(int i = 0; i < len; i++)
            {
                build(wordDict[i]);
            }
            dfs(s, 0, "");
            return v;
     
        }
    };
  • 相关阅读:
    P1486 [NOI2004]郁闷的出纳员
    poj2155 Matrix
    [USACO10MAR]伟大的奶牛聚集Great Cow Gat…
    分布式相关学习整理
    分布式学习之JTA
    linux相关命令整理
    每日笔记-redis的理解及相关应用
    利用redis实现分布式锁知识点总结及相关改进
    每日笔记-类加载机制及相关拓展
    多线程学习系列-概述
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/16674047.html
Copyright © 2020-2023  润新知