题目:

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

代码:

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

tips:

用了一个二维dp的思路。

dp[i][j]表示s[i]到s[j]是否能被dict表示。

dp的顺序是从后往前走,相当于是从最下往上dp上三角阵

求递推项dp[i][j]用一个循环遍历:dp[i][k] dp[k+1][j] ( i <= k <= j )如果能找到一个使得dp[i][j]为true,则跳出。

这里有一个corner case就是k==j的时候,dp[j+1][j]没有意义;因此特殊处理一下这种case,直接查找dict中是否有s[i:j]。

完成之后,在思考这道题是否可以用滚动数组来做?这样空间复杂度就降低为了O(n)

================================================

这个并不是滚动数组,就是一个一维DP,如下。

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

tips:

1. 空间复杂度由O(n²)降低到了O(n)

2. 代码更简洁了

并不是滚动数组,就是一维的DP,只不过dp[i]的取值要由dp[0:i-1]所有历史过程来决定。

===============================================

第二次过这道题,一开始没思路,后来强迫自己想出来了一维DP的解法,最后写了出来。

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

【Word Break】cpp的更多相关文章

  1. 【Word Search】cpp

    题目: Given a 2D board and a word, find if the word exists in the grid. The word can be constructed fr ...

  2. 【word ladder】cpp

    题目: Given two words (beginWord and endWord), and a dictionary, find the length of shortest transform ...

  3. 【Word Break II】cpp

    题目: Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where e ...

  4. 【word xml】将word转化为xml格式后,如何在xml中卫word添加分页符

    1.首先在xml中找到我们需要添加分页符的位置 例如:我需要在这个第一部分上面添加一个分页符 2.找到这个[第一部分]这个位置之后,开始往上找,找到对应的位置 3.在</w:pPr>下方添 ...

  5. hdu 4739【位运算】.cpp

    题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...

  6. 【Implement strStr() 】cpp

    题目: Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if ne ...

  7. Hdu 4734 【数位DP】.cpp

    题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...

  8. POJ 1018 【枚举+剪枝】.cpp

    题意: 给出n个工厂的产品参数带宽b和价格p,在这n个工厂里分别选1件产品共n件,使B/P最小,其中B表示n件产品中最小的b值,P表示n件产品p值的和. 输入 iCase n 表示iCase个样例n个 ...

  9. 【Text Justification】cpp

    题目: Given an array of words and a length L, format the text such that each line has exactly L charac ...

随机推荐

  1. alias 新的命令='原命令 -选项/参数'。举例说明,alias l=‘ls -lsh' 将重新定义 ls 命令,现在只需输入 l 就可以列目录了。

    alias 新的命令='原命令 -选项/参数'.举例说明,alias l=‘ls -lsh' 将重新定义 ls 命令,现在只需输入 l 就可以列目录了.

  2. ConcurrentHashMap源码刨析(基于jdk1.7)

    看源码前我们必须先知道一下ConcurrentHashMap的基本结构.ConcurrentHashMap是采用分段锁来进行并发控制的. 其中有一个内部类为Segment类用来表示锁.而Segment ...

  3. jQuery-添加新元素的方法(append()、prepend()、before()、after())

    1.以 HTML 创建新元素 var txt1="<p>Text.</p>"; 2.以 jQuery 创建新元素 var txt2=$("< ...

  4. LeetCode Merge Sorted Array 合并已排序的数组

    void merge(int A[], int m, int B[], int n) { int *a=A,*b=B; ,j=; ||m==){ //针对特殊情况,比如A或B中无元素的情况 & ...

  5. HDU 1011 Starship Troopers星河战队(树形dp)

    题意 有n个洞穴编号为1-n,洞穴间有通道,形成了一个n-1条边的树, 洞穴的入口即根节点是1. 每个洞穴有x只bugs,并有价值y的金子,全部消灭完一个洞穴的虫子,就可以获得这个洞穴的y个金子. 现 ...

  6. FW 数据库迁移之从oracle 到 MySQL

    方式一: 手动方式导入导出 手动的方式导入, 就是操作步骤会比较繁琐一些. 对Table 的结构和数据: 1. 使用 SQL Developer 把 oracle 的 table 的schema 和 ...

  7. fopen, fdopen, freopen - 打开流

    SYNOPSIS (总览) #include <stdio.h> FILE *fopen(const char *path, const char *mode); FILE *fdopen ...

  8. 在主机端和设备端进行”incrementArray“并对结果进行比较

    实验思想: 在主机端将数据初始化后传输到设备端,设备端和主机端进行同样的操作对数据加1,然后将设备端的结果传输到主机,最后核对主机端的计算结果和设备端的计算结果是否一直. // incrementAr ...

  9. 快速搭建lvs + keepalived + nginx

      环境:   VIP         192.168.2.224 LVS        192.168.2.217     centos7 nginx1    192.168.2.231     c ...

  10. 一个简单的linux下设置定时执行shell脚本的示例

    很多时候我们有希望服务器定时去运行一个脚本来触发一个操作,比如说定时去备份服务器数据.数据库数据等 不适合人工经常做的一些操作这里简单说下 shell Shell俗称壳,类似于DOS下的command ...