使用以下算法(来自Leetcode):
给定非空字符串s和包含非空字列表的字典wordDict,确定s是否可以被分段为一个或多个字典单词的空格分隔序列。您可能认为该词典不包含重复的单词。
例如,给定 s =" leetcode", dict = [" leet"," code"]。
返回true,因为" leetcode"可以分段为" leet code"。
天真的解决方案如下:
public class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
return word_Break(s, new HashSet(wordDict), 0);
}
public boolean word_Break(String s, Set<String> wordDict, int start) {
if (start == s.length()) {
return true;
}
for (int end = start + 1; end <= s.length(); end++) {
if (wordDict.contains(s.substring(start, end)) && word_Break(s, wordDict, end)) {
return true;
}
}
return false;
}
}
时间复杂度列为O(n ^ n),因为它的递归树有多大。我完全同意递归树的最后一级有N ^ N个元素,但是那个级别之前没有N ^(N-1)?所以我们正在研究N ^ N + N ^(N-1)+ N ^(N-2)...导致更高的时间复杂度正确吗?
答案 0 :(得分:2)
当我们谈论时间复杂性和特别是Big-O表示法时,我们只需要参考增长最快的因子。因此,我们写N^N + N^(N-1)...
时TIME(N^N + N^(N-1)...)
可能是正确的,但这相当于O(N^N)
,因为N^N
是增长最快的因素。
例如,我可以在TIME(N^2 + N + 123)
中运行一些算法,因为N^2
是增长最快的部分,我们只是说TIME(N^2 + N + 123) = O(N^2)
。
答案 1 :(得分:2)
由于项N ^(N-2),N ^(N-3),... N ^(1)小于N ^(N-1),我们可以推导出N ^(N-1) )+ N ^(N-2)+ ... + N ^ 1小于N * N ^(N-1)= N ^ N因此您的总和小于2 * N ^ N = O(N ^ N)
答案 2 :(得分:2)
让我们从时间复杂度函数的上限开始一个简单的递归关系(即假设它在没有找到匹配的情况下整个循环):
此处i
为start
,N
为s.length()
。每个术语对应于:
word_Break
对start = end
进行递归调用,其中end
为j
第二名:使用长度为wordDict.contains
的子字符串调用end - start + 1
。
既然wordDict
是一个哈希集,这个调用是O(L)
,其中L
是输入词的长度(因为我们需要复制子串并对其进行哈希)
展开:
(Wolfram alpha的最后一步)
这与你的消息来源完全不同。
作为我答案的补充支持,让我们做一个数值测试:
uint64_t T(uint32_t N, uint32_t start)
{
if (start >= N) return 1;
uint64_t sum = 0;
for (uint32_t end = start + 1; end <= N; end++)
sum += (end - start + 1) + T(N, end);
return sum;
}
结果:
N T(N)
-----------------
1 3
2 9
3 22
4 49
5 104
6 215
7 438
8 885
9 1780
10 3571
11 7154
12 14321
13 28656
14 57327
15 114670
16 229357
17 458732
18 917483
19 1834986
20 3669993
21 7340008
22 14680039
23 29360102
24 58720229
25 117440484
26 234880995
27 469762018
28 939524065
29 1879048160
30 3758096351
31 7516192734
32 15032385501
33 30064771036
34 60129542107
时间复杂度的对数比例图:
正如您所看到的那样,这是线性的,这意味着时间复杂度的格式为a^N
而不是 N^N
。
相比之下,T(N) = O(N^N)
会给出以下情节:
哪个不是线性的,并且很多更快(注意垂直轴上的数字)。