[leetcode] Word Break

来源:互联网 发布:qq好友定位软件 编辑:程序博客网 时间:2024/05/22 00:18

1、题目描述

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

2、分析思路1

最常用的算法是穷举法,即从第一个字母开始,判断形成的单词是否在dict中。

如果在,继续向后遍历。如果不在,继续向后扩大搜索范围,直到形成在dict中的单词。如果到最后一直没有,返回false。

bool wordBreak(string s, unordered_set<string> &dict) {    if(dict.find(s) != dict.end()){        return true;    }        bool finished = false;    for(int i = 1; i< s.length(); i++){        string first = s.substr(0, i);        if(dict.find(first)!=dict.end()){            if(i == s.length()){                finished = true;            }else{                string second = s.substr(i);                finished = wordBreak(second, dict);                if(finished){                    break;                }            }        }    }    return finished;}

之前找到过的词,并没有被记录,也就是没有记忆的。

超时的case:Last executed input:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", ["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]

需要逐步搜索,因此时间复杂度为O(n^2)这个显然没有被accepted。

外层第一次遍历,a在dict中,进入递归,一直到b不在词典中,遍历失败。并且每一次都需要这样的尝试。

需要执行第二次遍历,aa在词典中,进入递归,一直到ab不在词典中。

3、分析思路2

采用递归的思想,将前面能够在词典中的单词,都记录下来到一个数组中。

bool wordBreak(string s, unordered_set<string> &dict) {    size_t nsize = s.size();    int i=0,j=0;    bool *dp = new bool[nsize];    memset(dp,false,sizeof(dp));        for(i=0;i<nsize;++i)    {        dp[i] = ((dict.find(s.substr(0,i+1))!=dict.end()) ? true : false);        if(dp[i])        {            continue;        }        else        {            for(j=0;j<i;++j)            {                if(dp[j])                {                    dp[i] = ((dict.find(s.substr(j+1,i-j))!=dict.end())?true:false);                                                                             if(dp[i])                    {                        break;                    }                }            }        }    }    bool result = dp[nsize-1];    delete []dp;    return result;}

时间复杂度O(n*n),因为辅助数组的存在,之前判断过了就不需要重新判断了。轻松accepted。


0 0