完美的正方形leetcode缺少带有递归解决方案的测试用例

时间:2017-09-03 07:16:04

标签: python algorithm recursion dynamic-programming

尝试使用递归解决此problem,但输入7168得到错误答案。

  

给定正整数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.请不要建议其他方法来解决这个问题,因为我已经尝试过它并且它有效。我在这里只是知道这个逻辑的问题。

2 个答案:

答案 0 :(得分:1)

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

recursive(X, Y, dp)recursive(X, Z, dp)如果dp[X]返回X in dp,但如果dp[X] + ydp[X] + z,则分别返回dp[X]y = R - Y还没有记忆(z = R - ZRresult dp[X]的值result。{/ p>

我会完全摆脱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

HttpClient

答案 1 :(得分:1)

首先,您有一个拼写错误:m应为large_no

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

这意味着你可能会缓存一个比预期更大的值,而你的算法是错误的。虽然算法是错误的,但7168是产生错误结果的第一个值。

删除result参数,将return result+1更改为return 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]
相关问题