为何elif语句会破坏打家劫舍问题的动态规划解法?
打家劫舍问题(Robber Problem)
小偷不能盗窃相邻房屋,需最大化劫掠金额。
示例
- 输入:
arr = [2, 10, 3, 6, 8, 1, 7] - 输出:
25 - 解释: 小偷能获得的最大金额为25,通过盗窃第1、4、6号房屋(
arr[1]+arr[4]+arr[6] = 10+8+7 = 25)
可正常运行的解法
def rob(arr): arr = tuple(arr) memory = {} def helper(i=0): if i >= len(arr): return 0 if i not in memory: steal = arr[i] + helper(i+2) skip = helper(i+1) memory[i] = max(steal, skip) return memory[i] return helper()
返回错误结果的解法(返回0)
def rob(arr): arr = tuple(arr) memory = {} def helper(i=0): if i >= len(arr): return 0 elif memory[i]: return memory[i] else: steal = arr[i] + helper(i+2) skip = helper(i+1) memory[i] = max(steal, skip) return memory[i] return helper()
差异原因解析
两个解法的核心差异在于缓存判断逻辑:
- 正确解法:用
if i not in memory:判断当前索引i是否已存入缓存字典。只要i不在缓存中,就重新计算并存储结果;否则直接返回缓存值,逻辑完全正确。 - 错误解法:用
elif memory[i]的逻辑存在致命问题:- 当
i不在memory的键中时,直接访问memory[i]会触发KeyError异常,程序会崩溃。你提到它返回0,大概率是测试时误用了defaultdict(int)这类默认字典(访问不存在的键会返回0),但即使如此,逻辑依然错误。 - 就算缓存中存在
i,memory[i]的判断是检查值是否为真(非0、非空等)。如果某个索引的最大金额确实是0,这行代码会误以为没有缓存,进入else分支重复计算,导致逻辑混乱,最终返回错误结果。
- 当
简单来说,错误解法把「检查键是否存在」写成了「检查键对应的值是否为真」,完全偏离了缓存的正确逻辑。
内容的提问来源于stack exchange,提问作者jbuddy_13
相关产品推荐
相关产品推荐

