完美的正方形leetcode丢失递归解决方案的测试用例

问题描述:

尝试用递归解决这个problem但输入7168得到错误的答案。完美的正方形leetcode丢失递归解决方案的测试用例

给定一个正整数n,求出与n和的完美平方数(例如,1,4,9,16,...)的最小数。例如,给定n = 12,返回3,因为12 = 4 + 4 + 4;给定的n = 13,返回2,因为13 = 4 + 9

def recursive(self, n, result, dp): 
    if n in dp: 
     return dp[n] 
    #very large number 
    large_no = 1 << 31 
    if n < 1: 
     return 0  
    #checking if n is a square or not? 
    r = n**0.5 
    if int(r)*int(r) == n: 
     return result + 1 
    #iterate from square root till 1 checking all numbers 
    r = int(r) 
    while r >= 1: 
     large_no = min(large_no, self.recursive(n - int(r)*int(r), result + 1, dp)) 
     r -= 1 
    #memoize the result 
    dp[n] = large_no 
    return large_no 

我打电话上述函数为这样:self.recursive(7168,0,{})

回答应该是4但我越来越5.请不要建议替代方法来解决这个问题,因为我已经尝试过它们,它的工作原理。我在这里只是知道这个逻辑的问题。

+1

添加打印到顶部方法:'print(n,result,dp)'。运行它的一小部分(例如12),看看你正在记忆的值。他们对我来说似乎是错误的:例如'{2:4,3:4,5:6,...}'。那是你打算做什么的?通常情况下,你想记住正确的答案:例如'{2:2,3:3,4:1等]'。也许我不明白你的算法。 – FMc

+0

那么什么是7168的最佳四项分解(你的代码没有找到)? – NPE

+0

@NPE(80,16,16,16) –

首先,你有一个错字:m应该large_no

但是你错误地使用了dp:你应该缓存最小的方式来写i作为平方和,但你实际上缓存了你碰巧到达的任何路径的结果。

这意味着你可能会缓存一个意外的大于必要值的值,并且你的算法是错误的。虽然算法是错误的,但7168是第一个产生错误结果的值。

result参数,改变return result+1return 1和你的递归调用:

large_no = min(large_no, 1+self.recursive(n - int(r)*int(r), dp)) 

一个清理后,工作代码的版本:

def recursive(n, dp): 
    if n in dp: 
     return dp[n] 
    if n == 0: return 0 
    best = n 
    for r in xrange(int(n**0.5), 0, -1): 
     best = min(best, 1 + recursive(n - r*r, dp)) 
    dp[n] = best 
    return dp[n] 
+0

如果dp [i]代表达到i的最小平方,其中j从1开始到i的平方根,则递归关系是相同的:dp [i] = min(1 + dp [i-j * j])。 –

我认为问题在于您将result传递给您的递归,但不要在记忆中考虑它。

recursive(X, Y, dp)recursive(X, Z, dp)都分别返回dp[X]如果X in dp但返回dp[X] + ydp[X] + z,如果dp[X]尚未memoized(其中y = R - Yz = R - Z,与Rdp[X]得到memoized的result值)。

我会摆脱result干脆:

def recursive(self, n, dp): 
    if n in dp: 
     return dp[n] 
    #very large number 
    large_no = 1 << 31 
    if n < 1: 
     return 0  
    #checking if n is a square or not? 
    r = n**0.5 
    if int(r)*int(r) == n: 
     return 1 
    #iterate from square root till 1 checking all numbers 
    r = int(r) 
    while r >= 1: 
     large_no = min(large_no, self.recursive(n - int(r)*int(r), dp)) 
     r -= 1 
    #memoize the result 
    dp[n] = large_no + 1 
    return large_no + 1 
+0

这很有帮助,但因为(我的方法)超时,所以无法将此答案标记为正确。 –

+0

sys.setrecursionlimit(10000)当它设置它修复问题并正确地回答它4。 –