Word Break && Word Break II

Word Break && Word Break II

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

意思:判断一个字符串,是否可以由字典中的单词组成,如上面的leetcode可以由字典中的leet 和 code组成,可以的话,返回true,否则,返回false

思路:定义一个数组dp[],dp[i]表示字符串的前i个字符能否用字典表示,初始化dp[0]=true,i从1开始,那么对于前i+1个字符,我们需要判断在前i个字符串中存不存在一个点j,这个点dp[j]为true,并且[j,i]的字符串在字典中出现

dp[j]&&substr(j,i-j)   此时的j 从 0 到 i-1

拿上面的leetcode来说,当  i=4,此时表示leet单词是否在字典中存在,因为 dp[0]&&substr(0,4-0)
此时substr(0,4-0)=leet 在字典中存在,所以 dp[4]=true,依次往后求,直到求的dp[size].

代码:


class Solution {
public:
    bool wordBreak(string s, unordered_set<string>& wordDict) {

        int size=s.size();
        vector<bool> dp(s.length() + 1, false);

        dp[0]=true;

        for(int i=1;i<=size;i++)
        {
            string temp;
            for(int j=0;j<i;j++)
            {

                if(dp[j]&&wordDict.find(s.substr(j,i-j))!=wordDict.end())
                {
                    dp[i]=true;
                    break;
                }
            }
        }

        return dp[size];

    }
};

Word Break II

思路,从第一个字符开始,往后找,找到一个在字典中出现的单词,然后用一个temp拼接,接着在生下来的字符串中进行查找,将temp传过去,一次类推,直到遍历完整个字符串。

代码如下:


class Solution {
public:
    vector<string> wordBreak(string s, unordered_set<string>& wordDict) {

      vector<string> result;
      int len=s.size();
      string temp;
      for(int i=0;i<len;i++)
      {
          temp=s.substr(0,i+1);

          if(wordDict.find(temp)!=wordDict.end())
          {
              findNext(s,i+1,temp,wordDict,result);

          }

          temp="";
      }

      return result;

    }

    void findNext(string s,int start,string temp,unordered_set<string>& wordDict,vector<string>&result)
    {
        if(start>=s.length())
        {
            result.push_back(temp);
            return;
        }

        string now;
        for(int i=start;i<s.length();i++)
        {
            now=s.substr(start,i-start+1);
            if(wordDict.find(now)!=wordDict.end())
            {
                findNext(s,i+1,temp+‘ ‘+now,wordDict,result);
            }
        }
    }
};

下面有一中优化做法,参考博客:Word berak Ⅱ

1 使用二维表vector<vector<int> >tbl记录,记录从i点,能否跳到下一个break位置。如果不能,那么tbl[i]就为空。如果可以,就记录可以跳到哪些位置。

2 利用二维表优化递归回溯法。
优化点:
如果当前位置是start,但是tbl[start]为空,那么就是说,这个break位置不能break整个s串的,直接返    回上一层,不用搜索到下一层了。

class Solution {
public:
    //2014-2-19 update
    vector<string> wordBreak(string s, unordered_set<string> &dict)
    {
        vector<string> rs;
        string tmp;
        vector<vector<int> > tbl = genTable(s, dict);
        word(rs, tmp, s, tbl, dict);
        return rs;
    }
    void word(vector<string> &rs, string &tmp, string &s, vector<vector<int> > &tbl,
        unordered_set<string> &dict, int start=0)
    {
        if (start == s.length())
        {
            rs.push_back(tmp);
            return;
        }
        for (int i = 0; i < tbl[start].size(); i++)
        {
            string t = s.substr(start, tbl[start][i]-start+1);
            if (!tmp.empty()) tmp.push_back(‘ ‘);
            tmp.append(t);
            word(rs, tmp, s, tbl, dict, tbl[start][i]+1);
            while (!tmp.empty() && tmp.back() != ‘ ‘) tmp.pop_back();//tmp.empty()
            if (!tmp.empty()) tmp.pop_back();
        }
    }
    vector<vector<int> > genTable(string &s, unordered_set<string> &dict)
    {
        int n = s.length();
        vector<vector<int> > tbl(n);
        for (int i = n - 1; i >= 0; i--)
        {
            if(dict.count(s.substr(i))) tbl[i].push_back(n-1);
        }
        for (int i = n - 2; i >= 0; i--)
        {
            if (!tbl[i+1].empty())//if we can break i->n
            {
                for (int j = i, d = 1; j >= 0 ; j--, d++)
                {
                    if (dict.count(s.substr(j, d))) tbl[j].push_back(i);
                }
            }
        }
        return tbl;
    }
};

上面的代码我改了一点点代码,使得更加容易阅读

class Solution {
public:
    //2014-2-19 update
    vector<string> wordBreak(string s, unordered_set<string> &dict)
    {
        vector<string> rs;
        string tmp;
        vector<vector<int> > tbl = genTable(s, dict);
        word(rs, tmp, s, tbl, dict);
        return rs;
    }
    void word(vector<string> &rs, string tmp, string &s, vector<vector<int> > &tbl,
        unordered_set<string> &dict, int start=0)
    {
        if (start == s.length())
        {
            rs.push_back(tmp);
            return;
        }
        for (int i = 0; i < tbl[start].size(); i++)
        {
            string t = s.substr(start, tbl[start][i]-start+1);
            if (!tmp.empty())
            {
                word(rs, tmp+‘ ‘+t, s, tbl, dict, tbl[start][i]+1);
            }
            else
            {
                 word(rs, t, s, tbl, dict, tbl[start][i]+1);
            }

        }
    }
    vector<vector<int> > genTable(string &s, unordered_set<string> &dict)
    {
        int n = s.length();
        vector<vector<int> > tbl(n);
        for (int i = n - 1; i >= 0; i--)
        {
            if(dict.count(s.substr(i))) tbl[i].push_back(n-1);
        }
        for (int i = n - 2; i >= 0; i--)
        {
            if (!tbl[i+1].empty())//if we can break i->n
            {
                for (int j = i, d = 1; j >= 0 ; j--, d++)
                {
                    if (dict.count(s.substr(j, d))) tbl[j].push_back(i);
                }
            }
        }
        return tbl;
    }
};

在判断的时候,如果为空,就表示是第一个单词,不用加空格,否则加空格,而上面的代码谢了很多还不易于理解

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-28 17:00:39

Word Break && Word Break II的相关文章

Word Break/Word Segment

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, givens = "leetcode",dict = ["leet", "code"]. Return true because &

reverse the string word by word

题目:Given an input string, reverse the string word by word. For example,Given s = "the sky is blue",return "blue is sky the". 要求: 1)首尾有空格的时候,反转后的string要将空格去掉 2)当string有多个连续空格的时候,只保留一个空格. 代码分析: 对多余空格剔除: 思路分析: 1)从原始s 的最末尾开始扫描,如果遇到空格,用whil

如何将latex转换为word之word插入.bib中的文献

论文一直用latex写的,投稿需要,现在要将latex的论文转换到word中.难点之一:插入以前bib中的文献. 工具准备: 1 MiKTeX核心,如果已经装个Tex软件,比如CTeX就不用装了. 2 JabRef,BibTeX形式的参考文献管理工具. 3 Bibtex4Word软件.解压后将文件夹中的"bibtex4word.dot"文件,复制粘贴至Word的启动文件夹.我的是Win8系统,所在路径是:C:\Users\Administrator\AppData\Roaming\Mi

Microsoft.Office.Interop.Word 创建word

Microsoft.Office.Interop.Word 创建word 转载:http://www.cnblogs.com/chenbg2001/archive/2010/03/14/1685746.html 功能总结或者完善. 一.添加页眉 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Linq; using System

PDF转Word、Word转PDF技巧

随着PDF文件的流行,与之相关的PDF转Word.Word转PDF的操作在日常办公中也是比较常见了,PDF转Word的方法也比较多,今天就给大家分享一种简单的转换文档格式的方法. 1.先打开手机,在手机应用市场上搜索"PDF转换大师",找到这个软件后,将其下载到安卓手机上. 2.然后打开软件,在软件上面有两个不同的转换功能,如果是将PDF转Word,点击上面的"PDF转其他格式",选择这项功能. 3.接着再找到想要转换的PDF文件,可在"全部文件"

[email&#160;protected] [139/140] Word Break &amp; Word Break II

https://leetcode.com/problems/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, givens = "leetcode",dict = ["leet"

18. Word Ladder &amp;&amp; Word Ladder II

Word Ladder Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that: Only one letter can be changed at a time Each intermediate word must exist in the dictionary For example,

Java开发中经典的小实例-(swich(){case:参数break;default: break;})

import java.util.Scanner; public class Test6 { public static void main(String[] args) {        // TODO Auto-generated method stub                        Scanner input =new Scanner(System.in);                System.out.println("pleace input your sex:(

[Word]解决Word中执行输入操作时后面字符自动被删除的问题

问题分析:这是由于当前输入方式为"改写",在此方式下,如果某个位置处后面有其他字符,当在此位置执行输入操作时,就会默认删除其后的所有字符. 解决方案:Word窗口下边缘状态栏,找到"改写"按钮,点击,使其切换为"插入",问题解决. 说明:如果找不到"改写"按钮,是因为被隐藏了.右键点击状态栏,可将此按钮调出来.