LintCode: Word Break

9 篇文章 0 订阅
8 篇文章 0 订阅
Word Break
30:00

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

Example

Given s = "lintcode", dict = ["lint", "code"].

Return true because "lintcode" can be break as "lint code".

Tags Expand  

原题地址:http://www.lintcode.com/en/problem/word-break/

这道题我从前一天的晚上一直纠结到第二天,然后在参考答案的帮助下终于解决了。

一开始最初的想法是用recursive去做,而且感觉这长的就像recursive,后来一提交发现超时。

然后想换成DP的方法试一试,初始化一个boolean数组dp dp[i]的值表示string s的子字符串(0,i)能否被dict中的字符所分割。

这样很容易得出DP方程:如果DP[ j ]为true, 那么存在i DP[ i ]为true 并且 dict包含substring(i,j) 即DP[ j ] = DP[ i ]+s.substring( i,j )。

然后很快写出了第一个版本的代码:

public class Solution {
    /**
     * @param s: A string s
     * @param dict: A dictionary of words dict
     */
    public boolean wordBreak(String s, Set<String> dict) {
        // write your code here 
        boolean[] check = new boolean[s.length()+1];
        check[0] = true;
        if (s == null || s.length() == 0){
            return true;
        }
        for (int i = 1; i<= s.length(); i++){
                for (int j = i-1;j>=0;j--){
                    if(check[j]){
                     String a = s.substring(j,i-j);
                      if (dict.contains(a)){
                        check[i] = true;
                        break;
                        }
                    }
                }
            
        }
        return check[s.length()];
        
       
    }
}

但是后来发现总是卡在一个测试用例上 S="aaaaaaa" , dict=""aaaa","aaa""上 一开始怎么也想不明白,以为是自己的下标出了问题,后来扔到IDE里面debug了之后才发现真是狡猾。我的程序只要循环到第三个a的时候就会满足dict.contains 所以我的字符串被分割成了aaa aaa a 自然最后结果为false。

最初我想的解决方案是在内层循环里面添加判断条件,但是后来发现不能解决问题。只能含泪重写


第二版代码(AC)

public class Solution {
    /**
     * @param s: A string s
     * @param dict: A dictionary of words dict
     */
    public boolean wordBreak(String s, Set<String> dict) {
        // write your code here
       int max = 0;
       for(String a:dict){
           max = Math.max(max,a.length());
       }
       boolean[] dp = new boolean[s.length()+1];
       dp[0] = true;
       
       for(int i = 1;i<=s.length();i++){
           for(int j = 1;j<=max&&j<=i;j++){
               if(dp[i-j]){
                   String word = s.substring(i-j,i);
                       if(dict.contains(word)){
                           dp[i]=true;
                           break;
                       }
                   }
               }
           }
       
       return dp[s.length()];
        
       
    }
    
}
思路其实就是对于每一个i 从0 到 i 把dict里面的单词都遍历一遍看满足不满足contain (代码中的max表示dict中长度最长的那个单词)这样就可以避免上述测试用例带来的bug

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值