首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何应用回溯算法?

如何应用回溯算法?
EN

Stack Overflow用户
提问于 2016-10-01 22:16:16
回答 3查看 147关注 0票数 4

我正在做一些Python课程的摘录,其中一个我被困在下面:

代码语言:javascript
复制
Given a digit sequence that represents a message where each uppercase letter 
is replaced with a number (A - 1, B - 2, ... , Z - 26) and space - 0. 
Find the number of the initial messages, from which that sequence 
could be obtained.

Example: 12345 - 3 (ABCDE, LCDE, AWDE)
         11 - 2 (AA, K)

朴素的解决方案很简单,而且它是简单的蛮力算法:

代码语言:javascript
复制
import string

def count_init_messages(sequence):
    def get_alpha(seq):
        nonlocal count

        if len(seq) == 0:
            count += 1
            return

        for i in range(1, len(seq) + 1):
            if seq[:i] not in alph_table:
                break
            else:
                get_alpha(seq[i:])

    alphabet = " " + string.ascii_uppercase
    # generate dictionary of possible digit combination
    alph_table = {str(n): alph for n, alph in zip(range(len(alphabet)), alphabet)}
    # counter for the right combination met
    count = 0
    get_alpha(sequence)

    return count

def main():
    sequence = input().rstrip()
    print(count_init_messages2(sequence))

if __name__ == "__main__":
    main()

但是,由于输入序列的长度可能长达100个字符,而且可能会有大量重复,我遇到了一个时间限制。例如,示例输入之一是2222222222222222222222222222222222222222222222222222222222222222222222 (possible messages number is 308061521170129)。由于我的实现重复次数太多,处理这样的输入需要很长时间。我想使用回溯算法,但我还没有意识到如何实现回忆录的后续结果。

如果有可能告诉我如何完成这项任务,我会很高兴的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-01 22:38:00

您必须解决的递归关系(其中s是一个数字字符串,而ab是个位数)如下:

代码语言:javascript
复制
 S("") = 1
 S(a) = 1
 S(s + a + b) = S(s+a) + (S(s) if ab is between 10 and 26)

它可以使用动态规划而不是回溯来计算。如果你做得对,那就是O(n)时间复杂度和O(1)空间复杂度。

代码语言:javascript
复制
def seq(s):
    a1, a2 = 1, 1
    for i in xrange(1, len(s)):
        a1, a2 = a1 + (a2 if 9 < int(s[i-1:i+1]) < 27 else 0), a1
    return a1

print seq('2222222222222222222222222222222222222222222222222222222222222222222222')
票数 4
EN

Stack Overflow用户

发布于 2016-10-01 22:24:13

查找表中最大的数字是26,所以您永远不需要查找长度大于2的字符串。相应地修改for循环。这可能足以使野蛮人的力量变得可行。

票数 0
EN

Stack Overflow用户

发布于 2016-10-02 04:05:42

您可能还识别了308061521170129作为第71斐波那契数。这种关系对应于Fibonacci数,它给出了“某些枚举问题的解”。最常见的问题是,计算1s和2s的组合数,它们之和为给定的n:有Fn+1方法可以做到这一点。

字符串中的每个连续子序列都可以划分为单数码或双位码,表示具有多个可能组合为1s和2s的n;因此,对于字符串中的每个这样的子序列,结果必须乘以(子序列的长度+ 1)斐波那契数(在702 s的情况下,我们只是将1乘以71斐波那契数)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39811963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档