[Lintcode] Word Break

Word Break

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

 

SOLUTION : 

1,首先看这个题的问题:true or false问题,直接先去考虑动归。

2,动归四要素:状态,方程,初始化,结果。

状态:f(x) 代表s的第x位之前可以被切分。

方程:考虑f(x) -->f(x + 1)将状态传递过来。f(i) = f(j) && s.(i,j) in dict 就是说前i位之前,有个j位置,j位置之前恰好可以完美切分,并且j后面的字母可以组成一个单词在dict里出现。

初始化: f(0) = true. 为什么定义这个呢?因为不定义这个不行,因为当我们划分字串为左边为0,右边为n的时候,而右边的n是一个字典string,那么左边必然要设置为true,才能使结果为true。所以空字符串我们需要认为true。

结果:就是f(s.length()), 注意字符位置跟数组更新答案的位置要对应,所以数组要大一个数。

代码:

public class Solution {
    /**
     * @param s: A string s
     * @param dict: A dictionary of words dict
     */
    // f(x) first of x in S, could be segment
    // f(i) = f(j) && s.substring(j,i) in dict
    // f(0) = true
    private int getLen(Set<String> dict){
        int maxLen = Integer.MIN_VALUE;;
        for (String word : dict){
            maxLen = Math.max(maxLen, word.length());
        }
        return maxLen;
    }
    public boolean wordBreak(String s, Set<String> dict) {
        boolean[] canSegment = new boolean[s.length() + 1];
        canSegment[0] = true;
        int maxLen = getLen(dict);
        if (s == null || s.length() == 0){
            return true;
        }
        for (int i = 1; i <= s.length(); i++){
            for (int lastWordLen = 1; lastWordLen <= maxLen && lastWordLen <= i; lastWordLen++){
                if (!canSegment[i - lastWordLen]){
                    continue;
                }
                String word = s.substring(i - lastWordLen, i);
                if (dict.contains(word)){
                    canSegment[i] = true;
                    break;
                }
            }
        }
        return canSegment[s.length()];
    }
}
View Code

 

posted @ 2015-11-10 02:28  Tri_tri_tri  阅读(279)  评论(0编辑  收藏  举报