回文分区时间复杂度
Posted
技术标签:
【中文标题】回文分区时间复杂度【英文标题】:Palindrome Partitioning Time Complexity 【发布时间】:2021-07-23 09:38:49 【问题描述】:我正在解决一个面试练习题:
Partition 使得分区的每个子串都是回文。返回 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 循环中完成的工作量。
任何见解/提示都会有所帮助。结合这一点,我无法写出递归关系..
非常感谢!!
【问题讨论】:
您似乎没有考虑函数成本中的递归调用。 @horcrux 你能详细说明一下吗? 【参考方案1】:简答
猜测解的指数成本和验证解的多项式成本。因此,总成本是指数函数和多项式函数的乘积。
长答案
在最坏的情况下,continue
语句将永远无法到达,因此每个循环都会有一个递归调用。在这种情况下,如果你有一个n
-character-long 单词,你将有n
for
循环,每个循环最多调用n-1
for
循环,每个循环最多调用n-2
for
循环...即,成本为O(n!)
!
但是,阶乘成本来自对上限的非常粗略的估计,我们可以更精确。
事实上,我们可以注意到当前chunk
的长度在每次递归调用和for 循环的每次迭代中都会减小。
例如,如果原始字符串长度为 4 个字符,则当前 chunk
的长度将为:
3
├─2
| ├─1
| | ├─0
| | 0
| 1
| ├─0
| 0
2
├─1
| ├─0
| 0
1
├─0
0
其中垂直步骤 (|
) 表示同栈级循环,而水平步骤 (─
) 表示递归调用。
不难看出,这是O(2^n)
,确实总步数正好是2^n-1
。
然后,考虑到每次迭代都必须反转chunk
,这显然需要花费O(n)
。
将两者结合起来,您会得到O(n*2^n)
。
【讨论】:
以上是关于回文分区时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章