这是一个算法问题:
给定一个字符串s和一个单词字典dict,在s中添加空格 构造一个句子,其中每个单词都是有效的字典单词。
返回所有可能的句子。
例如,给定s =" catsanddog",dict = [" cat"," cats","和", " sand"," dog"]。
解决方案是["猫与狗","猫沙狗"]。
解决方案如下,但我很难确定此解决方案的时间复杂性。有人可以给我一些提示,特别是如果采访者在采访中问这个时间的复杂性,是否有一种快速的方法可以在没有太多数学的情况下找到它?
public class Solution {
Map<String,List<String>> map = new HashMap();
public List<String> wordBreak(String s, Set<String> wordDict) {
List<String> res = new ArrayList<String>();
if(s == null || s.length() == 0) {
return res;
}
if(map.containsKey(s)) {
return map.get(s);
}
if(wordDict.contains(s)) {
res.add(s);
}
for(int i = 1 ; i < s.length() ; i++) {
String t = s.substring(i);
if(wordDict.contains(t)) {
List<String> temp = wordBreak(s.substring(0 , i) , wordDict);
if(temp.size() != 0) {
for(int j = 0 ; j < temp.size() ; j++) {
res.add(temp.get(j) + " " + t);
}
}
}
}
map.put(s , res);
return res;
}
}
答案 0 :(得分:2)
时间复杂度为O(2^n * n)
。
最大此类单词分隔符的数量为2^(n-1)
,bijection为二进制向量,长度为n-1
:对于两个字符之间的每个空格,您可以在那里打破单词(在向量中1或不在(向量中为0),为您提供2^(n-1)
这样的可能单词。
由于创建每个字符串,计算其哈希值并将其添加到集合中是O(n)
(子字符串的长度),因此得到O(2^n * n)
。
你得到的最坏情况是:
dict = [a, aa, aaa, aaaa, ....]
s = "aaaaaaaaa...a"
map
n
确保您不使用memoization进行重复工作。 (没有它,复杂性将是default()
的阶乘,但使用它可以避免重复工作,例如从头开始重新计算“aaa ... a | a | a”和“aa ... a | aa”的前缀“