Middle-题目92:139. 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”.
题目大意:
给出一个字符串s和一个字典dict,判断s是否可以拆分成一个或多个字典内单词的连接。
例如s=”leetcode”,dict=[“leet”,”code”]则可以。
题目分析:
方法一:朴素解法,超时。从字典中寻找能否匹配s的前缀,如果能,则向下搜索,如果不能,则退回来再找下一个能匹配s前缀的单词。因为字符串过长的时候,可能浪费很多时间在错误解上,故超时。
方法二:(动态规划,解法来自“快乐de胖虎”大神的博客)记dp[i]表示字符串s的前i个字符能否在字典中匹配,则初始化dp[0]=true,其余为false(规定任意字典都能表示空串),则转移方程如下:
Middle-题目92:139. Word Break_第1张图片
(这东西怎么在LaTeX里面打出来。。。)
即前i个字符能否匹配取决于前j个字符能否匹配并且后i-j个字符在字典中,因此求以上表达式的析取。
源码:(language:java)

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

成绩:
12ms,beats 31.03%,众数12ms,24.67%
Cmershen的碎碎念:
初次看到此题想到的是贪心算法,即找到就向下搜,但若s=”abc”,dict=[“ab”,”a”,”bc”]时则会先搜到”ab”这个错误解,而朴素的回溯法在面对s=”aaaaaaaaaaaaaaaaaab”,dict=[“a”,”aa”,”aaa”,”aaaa”,”aaaaa”]时会陷入很慢的搜索,因为无论如何向下搜索都是错误解,且aaaaaaaaaaaaaaaaaa拆成若干a的组合有很多,算法都会遍历一遍,却不知字符b在字典里根本不存在。
不过此处提一个思考题,”aaaaaaaaaaaaaaaaaa”拆成1~5个a的连接的不同方法有多少种?
1-n个呢?

你可能感兴趣的:(Middle-题目92:139. Word Break)