Python动态规划实现子集和问题:代码迭代异常咨询
子集和DP代码问题排查与修复
嘿,我一眼就瞅见你代码里的核心问题啦——这是Python里创建二维列表的经典坑!
问题根源:错误的二维数组初始化
你写的 db = [[False] * col] * row 看似创建了 row 行 col 列的二维数组,但实际上,Python 中这种写法会让所有行都引用同一个列表对象。举个例子,当你执行 db[i][0] = True 时,所有行的第 0 列都会变成 True,因为它们本质上是同一个列表的不同引用!这就导致你在迭代 j 的时候,以为是在修改当前行的数据,但其实不小心改了所有行,前一行 db[i-1] 的数据自然就乱了,出现不符合预期的异常。
修复方案:用列表推导式创建独立行
把二维数组的初始化改成列表推导式,这样每一行都是一个全新的列表,互相独立:
db = [[False] * col for _ in range(row)]
这种写法会循环 row 次,每次都生成一个新的 [False] * col 列表,彻底避免了引用共享的问题。
额外的小优化
还有两个小细节可以调整,让代码更健壮:
- 不要用
input作为变量名——它是 Python 的内置函数,用它做变量会覆盖内置功能,改成input_list更安全。 - 返回值最好明确写成
db[row-1][col-1],而不是依赖循环结束后的i和j,虽然结果一样,但代码可读性更强,避免循环变量带来的歧义。
修复后的完整代码
def subsetSum(input_list, target): row = len(input_list) + 1 col = target + 1 # 正确初始化独立行的二维DP数组 dp = [[False] * col for _ in range(row)] # 初始化:和为0的子集始终存在(空集) for i in range(row): dp[i][0] = True for i in range(1, row): current_num = input_list[i-1] for j in range(1, col): # 情况1:不选当前数字,继承上一行的结果 dp[i][j] = dp[i-1][j] # 情况2:如果不选不行,且当前数字能加入,就看减去当前数字后的子集是否存在 if not dp[i][j] and j >= current_num: dp[i][j] = dp[i-1][j - current_num] # 返回最终结果:是否存在子集和为target return dp[row-1][col-1] target = 5 input_list = [1,3,9,2] print(subsetSum(input_list, target)) # 输出True,因为3+2=5
现在运行这段代码,你会发现前一行的数据再也不会乱掉了,DP的状态转移完全符合预期~
内容的提问来源于stack exchange,提问作者Satish Jonnala
相关产品推荐
相关产品推荐

