zoukankan      html  css  js  c++  java
  • LeetCode之“动态规划”:Word Break && Word Break II

      1. Word Break

      题目链接

      题目要求:

      Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

      For example, given
      s = "leetcode",
      dict = ["leet", "code"].

      Return true because "leetcode" can be segmented as "leet code".

      博文Word Break -- LeetCode提及了动态规划的思想:

      首先我们要决定要存储什么历史信息以及用什么数据结构来存储信息。然后是最重要的递推式,就是如从存储的历史信息中得到当前步的结果。最后我们需要考虑的就是起始条件的值。

      下边是该博文对该题目的分析:

      首先我们要存储的历史信息res[i]是表示到字符串s的第i个元素为止能不能用字典中的词来表示,我们需要一个长度为n的布尔数组来存储信息。然后假设我们现在拥有res[0,...,i-1]的结果,我们来获得res[i]的表达式。思路是对于每个以i为结尾的子串,看看他是不是在字典里面以及他之前的元素对应的res[j]是不是true,如果都成立,那么res[i]为true,写成式子是

      

      具体程序如下:

     1 class Solution {
     2 public:
     3     bool wordBreak(string s, unordered_set<string>& wordDict) {
     4         int szS = s.size();
     5         if(szS == 0)
     6             return false;
     7         
     8         vector<bool> dp(szS + 1, false);
     9         dp[0] = true;
    10         for(int i = 1; i < szS + 1; i++)
    11         {
    12             for(int j = i - 1; j > -1; j--)
    13             {
    14                 if(dp[j] && wordDict.find(s.substr(j, i - j)) != wordDict.end())
    15                 {
    16                     dp[i] = true;
    17                     break;
    18                 }
    19             }
    20         }
    21         
    22         return dp[szS];
    23     }
    24 };
    View Code

      2. Word Break II

      题目链接

      题目要求:

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

      其实这道题比上一道题理解来得容易,直接用Brute Force或者想直接利用上一题的结果来得到最终结果,都会超时。具体的,就是对输入进行检查,看看输入是否可以分解的,这样就可以跟超时了。

      Brute Force程序:

     1 class Solution {
     2 public:
     3     bool isValid(string s, unordered_set<string>& wordDict)
     4     {
     5         return wordDict.find(s) != wordDict.end();
     6     }
     7     
     8     void dfs(string s, string tmp, vector<string>& res, unordered_set<string>& wordDict)
     9     {
    10         if (s.size() == 0)
    11         {
    12             tmp.pop_back(); // delete blank space
    13             res.push_back(tmp);
    14             return;
    15         }
    16         
    17         int sz = s.size();
    18         for(int i = 1; i < sz + 1; i++)
    19         {
    20             string str = s.substr(0, i);
    21             if(isValid(str, wordDict))
    22                 dfs(s.substr(i), tmp + str + " ", res, wordDict);
    23         }
    24     }
    25     
    26     vector<string> wordBreak(string s, unordered_set<string>& wordDict) {
    27         vector<string> res;
    28         int szS = s.size();
    29         if(szS == 0)
    30             return res;
    31             
    32         vector<bool> dp(szS + 1, false);
    33         dp[0] = true;
    34         for(int i = 1; i < szS + 1; i++)
    35         {
    36             for(int j = i - 1; j > -1; j--)
    37             {
    38                 if(dp[j] && wordDict.find(s.substr(j, i - j)) != wordDict.end())
    39                 {
    40                     dp[i] = true;
    41                     break;
    42                 }
    43             }
    44         }
    45         
    46         if(dp[szS])
    47             dfs(s, "", res, wordDict);
    48         
    49         return res;
    50     }
    51 };
    View Code

      利用上一题的结果:

     1 class Solution {
     2 public:
     3     bool isValid(string s, unordered_set<string>& wordDict)
     4     {
     5         return wordDict.find(s) != wordDict.end();
     6     }
     7     
     8     void dfs(string s, string tmp, vector<string>& res, vector<int> inDictPos, unordered_set<string>& wordDict)
     9     {
    10         if (s.size() == 0)
    11         {
    12             tmp.pop_back(); // delete blank space
    13             res.push_back(tmp);
    14             return;
    15         }
    16         int sz = inDictPos.size();
    17         if (sz > 1)
    18         {
    19             for (int i = 1; i < sz; i++)
    20             {
    21                 int diff = inDictPos[i] - inDictPos[0];
    22                 if (diff <= s.size())
    23                 {
    24                     string subStr = s.substr(0, diff);
    25                     if (isValid(subStr, wordDict))
    26                     {
    27                         vector<int> _inDictPos(inDictPos);
    28                         _inDictPos.erase(_inDictPos.begin(), _inDictPos.begin() + i);
    29                         string tmpStr = s.substr(diff);
    30                         dfs(s.substr(diff), tmp + subStr + " ", res, _inDictPos, wordDict);
    31                     }
    32                 }
    33             }
    34         }
    35     }
    36     
    37     vector<string> wordBreak(string s, unordered_set<string>& wordDict) {
    38         // Implemented in Word Break I
    39         int szS = s.size();
    40         vector<bool> dp(szS + 1, false);
    41         vector<int> inDictPos;
    42         dp[0] = true;
    43         inDictPos.push_back(0);
    44         for(int i = 1; i < szS + 1; i++)
    45         {
    46             for(int j = i - 1; j > -1; j--)
    47             {
    48                 if(dp[j] && wordDict.find(s.substr(j, i - j)) != wordDict.end())
    49                 {
    50                     dp[i] = true;
    51                     inDictPos.push_back(i);
    52                     break;
    53                 }
    54             }
    55         }
    56         
    57         vector<string> res;
    58         if(dp[szS])
    59             dfs(s, "", res, inDictPos, wordDict);
    60         
    61         return res;
    62     }
    63 };
    View Code

      相比较之下,当然只用BF就够了,而且还来得简单。

  • 相关阅读:
    学习的原动力
    “六顶思考帽”给我的启示
    关于DataSet与Strongly typed DataSet几点思考(原创)
    设计模式之Singleton和Factory
    CentOS修改网络配置
    Proxmox VE(PVE)安装教程
    CentOS开启SELinux导致samba无法访问的解决办法
    nano编辑器使用教程
    CentOS 如何挂载硬盘
    PVE硬盘直通
  • 原文地址:https://www.cnblogs.com/xiehongfeng100/p/4566346.html
Copyright © 2011-2022 走看看