leetcode-word break-ZZ

题目, 反正就是一个string,要不自己在字典里,要不切几刀,切出来的每个词都在字典里

———————————————————————————————————————————————————————-

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

———————————————————————————————————————————————————————-

最笨的解法,DFS

public class Solution {
    public boolean wordBreak(String s, Set<String> dict) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        if (dict.contains(s)) return true;
        if (s==null || s.length()==0) return false;
        return helper(s, 0, dict);
    }

    public boolean helper(String s, int i, Set<String> dict) {
        int n = s.length();
        if (i>=n) return false;
        int j = i;
        while (j<n) {
            while(j<n && !dict.contains(s.substring(i,j+1))) {
                j++;
            }
            if (j==n) return false;
            boolean goodAfter = helper(s, j+1, dict);
            if (goodAfter) return true;
            j++;
        }
        return false;
    }
}

我不确定对: 没有额外空间,空间O(1)。每次recursion,都要loop O(n), 时间O(n^n)

毫无意外是会超时的,要加速基本要上DP了。关键是DP记录什么东西不好想,反正我是想了很久都没想到。最后看了大牛的答案才明白。还是bottom up approach。比如String长度为0,问题成立吗? 然后String长度为1,成立吗? 一直到n。所以dp就是记录从头开始的substring的长度和问题能否成立的关系。关键是dp[i]怎样可以利用dp[k], k=0,.., i-1的结果?就要在找0到i-1中找到一个k,使得dp[k] && dict.contains(s.substring(k, i))为真。意义是从0到k-1之间的substring,已经有办法用字典的词组成了,而且如果k到i-1之间的substring也在字典里,那么从0开始,长度为i的string就可以由字典里的词组成。

注意的是dp[0] == true是因为如果整个词都在字典里,那么就可以由字典的词组成。

优化解法:一维DP

public class Solution {
    public boolean wordBreak(String s, Set<String> dict) {
        int n = s.length();
        boolean[] dp = new boolean[n+1];
        dp[0] = true;
        for (int i=1; i<=n; i++) {
            for (int j=0; j<i; j++) {
                if (dp[j] && dict.contains(s.substring(j,i))) {
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[n];
    }
}

空间 O(n), 时间O(n^2)

这种方法好像在leetcode很常见,以后要总结一下。

http://stupidcodergoodluck.wordpress.com/2013/11/15/leetcode-word-break/

原文地址:https://www.cnblogs.com/forcheryl/p/3997290.html