码迷,mamicode.com
首页 > 其他好文 > 详细

LeetCode Word Break

时间:2015-01-23 13:21:09      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:

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

思路分析:这题如果暴力匹配,从前向后扫描s,看是否可以和dict中的词匹配,可以得到o(n^2)的solution。为了减少重复计算,我们想到用DP,从先向后保存判断是否可以segment的结果给后面复用。于是我们定义数组canSegmented,canSegmented[i]表示s[0...i]能否被segment,我们可以在最前面增加一个dummy字符,假设已经被dict包含,即canSegmented[0] = ture. 然后从前向后计算canSegmented[i],递推方程为

canSegmented[i] = true     if   canSegmented[k] == true 并且 s[k+1,i]在dictionary里面, 0=<k<i(注意k是尝试划分点,k=0就是不做划分)
                            = false    if    no such k exist.(也就是所有的划分都无法满足segment的条件)

k是我们尝试划分s[0...i]的位置,如果划分位置的标记数组值为true并且后面部分s[k+1,i]也被字典包含,则划分成功。如果所有的划分点都失败,则canSegmented[i]为false。有了递推方程,实现就很容易了,从前向后计算数组的元素值,最后返回canSegmented[s.length() - 1]。这题实现要注意java的substring(begin, end)函数是begin被包含,end不被包含。

AC Code

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


LeetCode Word Break

标签:

原文地址:http://blog.csdn.net/yangliuy/article/details/43054277

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!