Algorithm 动态规划文本对齐的时间复杂度

Algorithm 动态规划文本对齐的时间复杂度,algorithm,time-complexity,big-o,dynamic-programming,Algorithm,Time Complexity,Big O,Dynamic Programming,我一直在做一件事。我相信我已经找到了一个可行的解决方案,但是我对这个算法的运行时间感到困惑 到目前为止,我所做的研究已经将这个问题的动态规划解决方案描述为O(N^2),其中N是被证明的文本长度。对我来说,这种感觉是不正确的:我可以看到O(n)的调用必须进行,因为有N个后缀要检查,但是,对于任何给定的前缀,我们永远不会考虑将新行(或‘分裂点’)放在最大行长度 L< /强>。因此,对于任何给定的文本,最多有L个位置来放置分割点(这假设了最坏的情况:每个单词正好有一个字符长)。由于这种实现,这个算法不

我一直在做一件事。我相信我已经找到了一个可行的解决方案,但是我对这个算法的运行时间感到困惑

到目前为止,我所做的研究已经将这个问题的动态规划解决方案描述为O(N^2),其中N是被证明的文本长度。对我来说,这种感觉是不正确的:我可以看到O(n)的调用必须进行,因为有N个后缀要检查,但是,对于任何给定的前缀,我们永远不会考虑将新行(或‘分裂点’)放在最大行长度<强> L< /强>。因此,对于任何给定的文本,最多有L个位置来放置分割点(这假设了最坏的情况:每个单词正好有一个字符长)。由于这种实现,这个算法不是更准确地描述为O(LN)吗

@memoize
def justify(文本、行长度):
#如果文本小于行长度,请不要拆分
如果len(''.join(text))<行长度:
return[],math.pow(行长度-len(''.join(text)),3)
最佳成本,最佳分割=sys.maxsize,[]
对文本进行迭代,并考虑在每个单词之间进行拆分。
对于范围(1,长度(文本))中的拆分点:
长度=长度(“”.join(文本[:拆分点])
#此拆分超出了最大线长度:所有未来拆分点都不可接受
如果长度>直线长度:
打破
#递归计算该点之后文本的最佳分割点
未来分割,未来成本=调整(文本[分割点:],行长度)
成本=数学功率(线路长度-长度,3)+未来成本
如果成本<最佳成本:
最佳成本=成本
最佳分割=[split_point]+[split_point+n表示未来n次分割]
返回最佳分割,最佳成本
提前感谢您的帮助,
Ethan

首先,您的实现将远远超出您想要的理论效率。您正在通话中记忆长度为
N
的字符串,这意味着查找数据的缓存副本可能是
O(N)
。现在开始进行多个缓存调用,您的复杂度预算就已经超出

这可以通过将文本移到函数调用之外并只传递起始位置的索引和长度
L
来解决。您还在循环内部执行一个join,这是一个
O(L)
操作。如果小心一点,您可以将其改为
O(1)
操作


完成后,您将执行
O(N*L)
操作。正是出于您所想的原因。

关于记忆优化的好主意这里的规范DP算法检查所有起始位置和结束位置的惩罚(或成本)。ie)成本[i][j]=所有有效位置i,j(N^2)的(i,j)之间的惩罚
@memoize
def justify(text, line_length):

    # If the text is less than the line length, do not split
    if len(' '.join(text)) < line_length:
        return [], math.pow(line_length - len(' '.join(text)), 3)

    best_cost, best_splits = sys.maxsize, []

    # Iterate over text and consider putting split between each word
    for split_point in range(1, len(text)):
        length = len(' '.join(text[:split_point]))

        # This split exceeded maximum line length: all future split points unacceptable
        if length > line_length:
            break

        # Recursively compute the best split points of text after this point
        future_splits, future_cost = justify(text[split_point:], line_length)
        cost = math.pow(line_length - length, 3) + future_cost

        if cost < best_cost:
            best_cost = cost
            best_splits = [split_point] + [split_point + n for n in future_splits]

    return best_splits, best_cost