在阅读0494.目标和的二维 DP 解法时,发现两处可以改进的地方。
1:第一列的特殊初始化是冗余的
文章对最左列做了如下特殊处理:
// 初始化最左列,最左列其他数值在递推公式中就完成了赋值
dp[0][0] = 1;
int numZero = 0;
for (int i = 0; i < nums.size(); i++) {
if (nums[i] == 0) numZero++;
dp[i][0] = (int) pow(2.0, numZero);
}
但实际上这步是多余的。当 nums[i] == 0 时,递推公式为:
dp[i][0] = dp[i-1][0] + dp[i-1][0 - nums[i]]
= dp[i-1][0] + dp[i-1][0]
= 2 * dp[i-1][0]
只要正确初始化 dp[0][0] = 1,后续循环(for i in range(1, len(nums)): for j in range(0, target_sum + 1))会自动让 dp[i][0] 在遇到 0 元素时翻倍,等价于 2^numZero,无需手动计算。
2:引入空物品行,进一步简化初始化
对于二维数组解法,还可以探讨引入额外一行 -- 第 0 行,作为"不选任何物品"的基准状态,此时初始化只需一行:
而无需处理第一行的初始化。
以上两点均有助于降低二维 DP 初始化的心智负担。欢迎大家多多探讨!
在阅读0494.目标和的二维 DP 解法时,发现两处可以改进的地方。
1:第一列的特殊初始化是冗余的
文章对最左列做了如下特殊处理:
但实际上这步是多余的。当
nums[i] == 0时,递推公式为:只要正确初始化
dp[0][0] = 1,后续循环(for i in range(1, len(nums)): for j in range(0, target_sum + 1))会自动让dp[i][0]在遇到 0 元素时翻倍,等价于2^numZero,无需手动计算。2:引入空物品行,进一步简化初始化
对于二维数组解法,还可以探讨引入额外一行 -- 第 0 行,作为"不选任何物品"的基准状态,此时初始化只需一行:
而无需处理第一行的初始化。
以上两点均有助于降低二维 DP 初始化的心智负担。欢迎大家多多探讨!