题目链接:https://leetcode.com/problems/target-sum/
题解:
首先转化问题:令取正的数为A,取负的数为B,则要求sum(A)-sum(B)=S,两边加上sum(A)+sum(B),得到sum(A)-sum(B)+sum(A)+sum(B)=S+sum(A)+sum(B),即2*sum(A)=S+sum(nums),原问题转化为子数组和问题,使子数组和为(S+sum(nums))/2. 相似题目参考https://blog.youkuaiyun.com/scut_salmon/article/details/89283520
子数组和问题,若暴力求解,枚举数组每个元素是否加入,复杂度为2^n;考虑动态规划方法,即根据前n-1个数的和情况,推导前n个数的和情况。
令dp[i][j]表示前i个数和为j的子数组个数,则得到如下动态规划公式:
if j>=nums[i-1]:
dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i-1]]
else:
dp[i][j] = dp[i-1][j]
一些细节
1. 分析和情况有两种方式,一是枚举前n个数所有和的种类,然后前n+1个数的和种类为前n个数和的种类+在其基础加上第n+1个数+只算第n+1个数,这时的数据类型应该选择字典,字典的key为各种可能的和,value为各种和的子数组个