如何解决回文分区时间复杂度 简答长答案
我正在解决一个面试练习题:
Partition s 使得分区的每个子串都是一个回文。返回 s 的所有可能的回文分区。
我的解决方案如下,并被接受。
def partition(self,s: str) -> List[List[str]]:
ans = []
def bt(w,curr):
if not w:
ans.append(curr)
else:
for l in range(1,len(w)+1):
chunk = w[:l]
if ''.join(reversed(chunk)) != chunk:
continue
bt(w[l:],curr + [chunk])
bt(s,[])
return ans
解决方案中给出的时间复杂度为 O(N * 2^N)
我明白:
- 有 2^(N-1) 个可能的分区,
- 在最坏的情况下,任何分区都会产生回文,
- 检查回文与输入的大小呈线性关系。
但我正在努力估计在 for 循环中完成的工作量。
任何见解/提示都会有所帮助。结合这一点,我无法写出递归关系..
非常感谢!!
解决方法
简答
猜测解的代价是指数式的,而验证解的代价是多项式的。因此,总成本是一个指数函数和一个多项式的乘积。
长答案
在最坏的情况下,永远不会到达 60b725f10c9c85c70d97880dfe8191b3
语句,因此每个循环都将进行一次递归调用。在这种情况下,如果您有一个 continue
字符长的单词,您将有 n
n
个循环,每个循环最多调用 for
{{1} } 循环,每个循环最多会调用 n-1
for
次循环......即成本是 n-2
!
然而,阶乘成本来自对上限的非常粗略的估计,我们可以更精确。
事实上,我们可以注意到当前 for
的长度在每次递归调用和 for 循环的每次迭代中都会减少。
例如,如果原始字符串长度为 4 个字符,则当前 O(n!)
的长度为:
chunk
其中垂直步骤 (chunk
) 表示相同堆栈级别的循环,水平步骤 (3
├─2
| ├─1
| | ├─0
| | 0
| 1
| ├─0
| 0
2
├─1
| ├─0
| 0
1
├─0
0
) 表示递归调用。
很容易看出这是|
,实际上总步数正好是─
。
然后,考虑到对于每次迭代,您必须反转 O(2^n)
,这显然会花费 2^n-1
。
将两者结合,得到 chunk
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。