【问题标题】:Minimum Jumps required from given number to 1从给定数字到 1 所需的最小跳跃次数
【发布时间】:2021-01-20 00:37:23
【问题描述】:

我正在尝试解决下面给出的问题:(我使用递归解决了它,但我很难尝试使用缓存来防止重新计算许多相同的步骤。 """ 给定一个正整数 N,找出达到 1 所需的最小步数。

有两种允许的步骤:

您可以将 N 递减到 N - 1。 如果 a * b = N,您可以将 N 递减为 a 和 b 中的较大者。

例如,给定 100,您可以通过以下路线分五步达到 1: 100 -> 10 -> 9 -> 3 -> 2 -> 1。 """

def multiples(num):
    ret = []
    start = 2
    while start < num:
        if num % start == 0:
            ret.append(num // start)
        start +=1
        if ret and start >= ret[-1]:
            break
    return ret if ret else None
def min_jumps_no_cache(num, jumps=0):
    if num == 1:
        return jumps
    
    mults = multiples(num)
    res = []
    res.append(min_jumps(num - 1, jumps +1))
    if mults:
        for mult in mults:
            res.append(min_jumps(mult , jumps +1))
    return min(res)

现在,我正在尝试在此处添加缓存,因为此解决方案的运行时间明显较长。但是我在覆盖缓存之前遇到了类似的问题,我很好奇是否有解决方案。

def min_jumps_cache(num, jumps=0, cache={}):

    if num == 1:
        return jumps
    if num in cache:
        return cache[num]
    
    mults = multiples(num)
    res = []
    
    temp = min_jumps_cache(num - 1, jumps +1, cache)
    res.append(temp)
    if mults:
        for mult in mults:
            res.append(min_jumps_cache(mult , jumps +1, cache))
    temp = min(res)
    cache[num] = min(temp, cache[num]) if num in cache else temp
    return temp

在我看来,这里的问题是,在您计算出“左右”解决方案以找到答案之前,您无法真正缓存答案。我这里还有什么遗漏的吗?

【问题讨论】:

    标签: algorithm recursion memoization


    【解决方案1】:

    就目前而言,您的解决方案很好。

    但是,自下而上执行广度优先解决方案会更有效。 (这可以简单地进行更多优化。对读者来说是一个练习。)

    def path (n):
        path_from = {}
        queue = [(1, None)]
        while True:
            value, prev = queue.pop(0)
            value not in path_from:
                path_from[value] = prev
                if value == n:
                    break # EXIT HERE
                queue.append((value+1, value))
                for i in range(2, min(value+1, n//value + 1)):
                    queue.append((i*value, value))
    
        answer = []
        while n is not None:
            answer.append(n)
            n = path_from[n]
    
        return(answer)
    
    print(path(100))
    

    【讨论】:

    • 顺便说一句,我确实通过自下而上和自上而下的搜索来优化我的副本,直到它们在中间相遇。然后,我在 1..1_000_000 范围内搜索具有最长路径的数字。记录保持者为 85643,其路径为 1, 2, 3, 9, 81, 891, 892, 10704, 10705, 85640, 85641, 85642, 85643
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 2019-01-08
    • 2022-01-06
    • 1970-01-01
    • 2010-12-07
    • 1970-01-01
    相关资源
    最近更新 更多