Word Break

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

题目:字符串拆分,且拆分的单词都在dict中,求是否可拆分。

分析:

方法一、暴力破解,从前往后扫描,找到第一个在dict中的单词a后,递归求解剩余的部分是否可拆分。如果找到解就结束。否则重新a后面添加元素来拆分。

思路比较清晰,但是对于长的串,超时。O(n^n)

代码:

class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
        int len=s.size();
        if(len<1) return true;
        bool res;
        for(int j=1;j<=len;j++){
            string t=s.substr(0,j);
            unordered_set<string>::iterator it=dict.find(t);
            if(it!=dict.end()){
                 res=wordBreak(s.substr(j),dict);
                 if(res) return res;//找到符合的分割,返回,否则继续往下找。
		 else continue;
            }
        }
        return false;
    }
};

方法二:在暴力的基础上剪枝,添加一个cannotmatch的set,用来记录之前无法在dict中找到的串。

代码:Accepted

class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
        if(s.length()<1) return true;
        set<string> cannotmatch;
        return wordBreakHelper(s,dict,cannotmatch);
        
    }
    
    bool wordBreakHelper(string s, unordered_set<string> &dict, set<string> &cannotmatch) {//剪枝cannotmatch
        int len=s.size();
        if(len<1) return true;
        bool res;
        for(int j=1;j<=len;j++){
            string t=s.substr(0,j);
            unordered_set<string>::iterator it=dict.find(t);
            if(it!=dict.end()){
                string partofs=s.substr(j);//出去匹配部分,剩余的串
                set<string>::iterator it=cannotmatch.find(partofs);
                if(it!=cannotmatch.end()) continue;//如果后边部分在不能匹配集合中,直接试探下一个长度
                 else{
                     res=wordBreakHelper(partofs,dict,cannotmatch);
		     if(res) return res;//找到符合的分割,返回,否则继续往下找。
		     else cannotmatch.insert(partofs);//如果partofs还是不能拆分,添加到我们的cannotmatch 集合中。
                 }
            }
        }
        return false;
    }
};

方法三:DP,题目看起来像dp,却想不清楚。google之。使用一个bool数组t[],t[i]表示0-(i-1)该字符串是否可拆分。最后返回t[len]即可。

i从0到len-1 开始遍历:时间复杂度O(n*m) n表示字符串长度,m表示字典单词数目。空间复杂度O(n)

  1. 如果t[i]为ture,说0-(i-1)部分可拆分,然后去遍历dict中的单词,是否是string s从i往后同长度可以得到的单词。

如果dict中存在这样的单词,对应所有的 true[i+len]=true;

如果所有的dict都没有,t[i]是默认的false。

代码:

class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
        if(s.length()<1) return true;
        int len=s.length();
        bool t[len+1];//={false};//t[i] 0-(i-1)是否可分 初始化为false
        memset(t,0,len+1);
        t[0]=true;//相当于空串"" 可拆分
        
        for(int i=0;i<len;i++){
            if(t[i]==false) continue;//如果0-(i-1)不可拆分,i之后的串即使可拆分,整个串也是不可拆分的。
            
            unordered_set<string>::iterator it=dict.begin();
            for(;it!=dict.end();it++){
                string strdict=(*it);
                int lenstr=strdict.length();
                int end=i+lenstr;//可以达到的末尾下标
                
                if(end > len) continue;//比源字符串 长
                if(t[end]==true) continue;//本来就是true,直接继续扫描字典的下一个单词
                
                if(s.substr(i,lenstr)==strdict){
                    t[end]=true;
                }
                
            }
            
        }//for i
        return t[len];
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值