kSum
关于3Sum可以,先遍历第一个数,剩下的和求2Sum
对于kSum的问题,很容易想到使用动态规划,问题规模由3个方面:元素个数n,kSum的k,以及目标target
状态方程为:dp[n][k][target] = dp[n-1][k-1][target-arr[n]] (选第n个数)+ dp[n-1][k][target](不选第n个数)
为可能性问题,最后必须装满,也就是k=0时,target =0才能时找到了一个方案,所以dp[n][k][target] = dp[n-1][k-1][target-arr[n]] or dp[n-1][k][target]
import numpy as np
def kSum(arr,target,k):
n = len(arr)
dp = np.full((n+1,k+1,target+1),False)
# 初始化,为可能性问题,也就是最后必须k和target都用完了,才是最后的解
# 不能使用dp[:][0][0] = True,这两个的赋值不一样,这里是一个容易出错的地方
for i in range(n+1):
dp[i][0][0] = True
for i in range(1,n+1):
for j in range(1,k+1):
# 这里是一个剪枝,假如k小于元素个数就没有必要考虑了
if j <= i:
for l in range(1,target+1):
# 注意边界,假如l-arr[i-1]<0,就没有意义了,只能取左边
if l-arr[i-1] >=0:
dp[i][j][l] = dp[i-1][j][l] or dp[i-1][j-1][l-arr[i-1]]
else:
dp[i][j][l] = dp[i-1][j][l]
return dp[n][k][target]
arr = [16,7,8,44,2,4,5,97,5,3]
print(kSum(arr,99,3))
print(kSum(arr,102,3))
False
True