Subset Sum
Subset Sum
sum
Given an array of 𝑎𝑟𝑟 [ 𝑖 ] ≥1
strictly positive
integers arr and a
strictly positive
integer k, count
the number of
subsets that sum
Given an array of strictly 𝑎𝑟𝑟 [ 𝑖 ] ≥1
positive integers arr and a
strictly positive integer k,
count the number of subsets
that sum up to k
input:
arr = [1, 2, 3, 1, 4],
k=6
output: 4
explanation: we have 4 subsets that sum up
to 6:
[1, 2, 3], [1, 1, 4], [2, 3, 1], and [2, 4]
knapsack(k, i)
knapsack
(k-weights[i], i+1)
knapsack(k, i+1)
knapsack(k, i)
knapsack
(k-weights[i], i+1)
knapsack(k, i+1)
subsets(k, i)
subsets
(k-arr[i], i+1)
subsets(k, i+1)
subsets(k, i)
subsets
(k-arr[i], i+1)
subsets(k, i+1)
when we take
arr[i] in our
subset
when we don't
take arr[i]
𝑘=0 →1
𝑖=¿ 𝑎𝑟𝑟 ∨→ 0
𝑘 <0 → 0
1 𝑖𝑓 𝑘= 0
[2, 4]
wouldn't count
if we swap
base cases
def subsets(arr, k, i=0):
if k == 0:
return 1
elif i == len(arr) or k < 0:
return 0
else:
return subsets(arr, k-arr[i], i+1)
+ subsets(arr, k, i+1)
1 𝑖𝑓 𝑘= 0
1 𝑖𝑓 𝑘= 0
.
.
.
subsets(k,
n)
def subsets(arr, k, i=0):
subsets(k,
if k == 0:
0)
return 1
elif i == len(arr) or k < 0:
return 0
else: subsets(k,
return subsets(arr, k-arr[i], i+1) 1)
+ subsets(arr, k, i+1)
.
.
.
𝑇 (𝑛 , 𝑘)=𝑂 ( 2 ) 𝑛
subsets(k,
n)
subsets(k,n)
.
.
𝑛+1 .
subsets(k,1)
𝑆 ( 𝑛 , 𝑘 )= 𝑛+1= 𝑂 ( 𝑛 )
subsets(k,0)
s(6,0) input:
arr = [1, 2, 3, 1,
4],
s(6,1) s(5,1)
k=6
s(6,5) s(5,5) s(4,5) s(3,5) s(2,5) s(1,5) s(0,5) s(-1,5) s(-2,5) s(-3,5)
s(6,0) input:
arr = [1, 2, 3, 1,
4],
s(6,1) s(5,1)
k=6
s(6,5) s(5,5) s(4,5) s(3,5) s(2,5) s(1,5) s(0,5) s(-1,5) s(-2,5) s(-3,5)
1
def subsets(arr, k, i=0, lookup=None): 2
lookup = {} if lookup is None else lookup
if (i, k) in lookup:
return lookup[(i, k)]
if k == 0: 3
return 1
elif i == len(arr) or k < 0:
return 0
else:
lookup[(i, k)] = subsets(arr, k-arr[i], i+1, lookup)
+ subsets(arr, k, i+1, lookup)
return lookup[(i, k)]
4
𝑖 ∈{0 , 1 , … ,𝑛 − 1}
𝑘∈ {𝑘0 , 𝑘0 −1 , … , 0 }
(𝑘 , 𝑖)∈{(𝑘¿ ¿ 0 , 0),(𝑘0 , 1), … ,(0 , 0)}¿
𝑖 ∈{0 , 1 , … ,𝑛 − 1}
𝑘∈ {𝑘0 , 𝑘0 −1 , … , 0 }
(𝑘 , 𝑖)∈{(𝑘¿ ¿ 0 , 0),(𝑘0 , 1), … ,(0 , 0)}¿
𝑛
𝑘 +1
dp[n-1][k] represents
the number of subsets
that sum up to k in the
part of arr from 0 to n-1
𝑘 +1
4
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1
1
4
if we don't take arr = [1, 2, 3, [1, 2, 3]
the last element and
1], [2, 3, 1]
arr = [1, 2, 3, k=6
1, 4],
k=6
3
dp[i][j] =
dp[i-1][j] +
4
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1
2
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1
2
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1
2
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1
2
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0
2
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0
2
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
input:j-arr[i] j
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
3
dp[i][j] =
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]]
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]] 1
(if j-arr[i] 0)
input:j-arr[i] j
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]] 1 2
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]] 1 2 2
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]] 1 2 2 3
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]] 1 2 2 3 4
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]] 1 2 2 3 4 4
(if j-arr[i] 0)
j-arr[i] j
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]] 1 2 2 3 4 4 4
(if j-arr[i] 0)
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4],
k=6
0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0
2 1 1 1 2 1 1 1
dp[i][j] =
3 1 2 2 3 3 2 2
dp[i-1][j] +
dp[i-1][j-arr[i]] 1 2 2 3 4 4 4
(if j-arr[i] 0)
def subsets(arr, k):
n = len(arr)
if k > sum(arr) or n == 0:
return 0
dp = [[0]*(k+1) for i in range(n)]
dp[0][0] = 1
if arr[0] <= k:
dp[0][arr[0]] = 1
for i in range(1, n):
for j in range(k + 1):
dp[i][j] = dp[i-1][j]
+ (dp[i-1][j-arr[i]] if j-arr[i] >= 0 else 0)
return dp[n-1][k]
def subsets(arr, k):
n = len(arr)
if k > sum(arr) or n == 0:
return 0
dp = [[0]*(k+1) for i in range(n)]
dp[0][0] = 1
if arr[0] <= k:
dp[0][arr[0]] = 1
for i in range(1, n):
for j in range(k + 1):
dp[i][j] = dp[i-1][j]
+ (dp[i-1][j-arr[i]] if j-arr[i] >= 0 else 0)
return dp[n-1][k]
def subsets(arr, k):
n = len(arr)
if k > sum(arr) or n == 0:
return 0
dp = [[0]*(k+1) for i in range(n)]
dp[0][0] = 1
if arr[0] <= k:
dp[0][arr[0]] = 1
for i in range(1, n):
for j in range(k + 1):
dp[i][j] = dp[i-1][j]
+ (dp[i-1][j-arr[i]] if j-arr[i] >= 0 else 0)
return dp[n-1][k]
def subsets(arr, k):
n = len(arr)
if k > sum(arr) or n == 0:
return 0
dp = [[0]*(k+1) for i in range(n)]
dp[0][0] = 1
if arr[0] <= k:
dp[0][arr[0]] = 1
for i in range(1, n):
for j in range(k + 1):
dp[i][j] = dp[i-1][j]
+ (dp[i-1][j-arr[i]] if j-arr[i] >= 0 else 0)
return dp[n-1][k]
def subsets(arr, k):
n = len(arr)
if k > sum(arr) or n == 0:
return 0
dp = [[0]*(k+1) for i in range(n)]
dp[0][0] = 1
if arr[0] <= k:
dp[0][arr[0]] = 1
for i in range(1, n):
for j in range(k + 1):
dp[i][j] = dp[i-1][j]
+ (dp[i-1][j-arr[i]] if j-arr[i] >= 0 else 0)
return dp[n-1][k]
def subsets(arr, k):
n = len(arr)
if k > sum(arr) or n == 0:
return 0
dp = [[0]*(k+1) for i in range(n)]
dp[0][0] = 1
if arr[0] <= k:
dp[0][arr[0]] = 1
for i in range(1, n):
for j in range(k + 1):
dp[i][j] = dp[i-1][j]
+ (dp[i-1][j-arr[i]] if j-arr[i] >= 0 else 0)
return dp[n-1][k]
𝑇 ( 𝑛 , 𝑘 )=𝑂 (𝑛𝑘)
def subsets(arr, k):
n = len(arr)
if k > sum(arr) or n == 0:
return 0
dp = [[0]*(k+1) for i in range(n)]
dp[0][0] = 1
if arr[0] <= k:
dp[0][arr[0]] = 1
for i in range(1, n):
for j in range(k + 1):
dp[i][j] = dp[i-1][j]
+ (dp[i-1][j-arr[i]] if j-arr[i] >= 0 else 0)
return dp[n-1][k]
𝑆 ( 𝑛 , 𝑘 )=𝑂 (𝑛𝑘)
def subsets(arr, k):
n = len(arr)
if k > sum(arr) or n == 0:
return 0
prev_dp = [0]*(k+1)
dp = [0]*(k+1)
prev_dp[0] = 1
if arr[0] <= k:
prev_dp[arr[0]] = 1
for i in range(1, n):
for j in range(k+1):
dp[j] = prev_dp[j] + (prev_dp[j-arr[i]] if j-arr[i] >= 0 else 0)
prev_dp = dp
dp = [0]*(k+1)
return prev_dp[k]
𝑆 ( 𝑛 , 𝑘 )=𝑂 (𝑘)
s(6,0) input:
arr = [1, 2, 3, 1,
4],
s(6,1) s(5,1)
k=6
s(6,5) s(5,5) s(4,5) s(3,5) s(2,5) s(1,5) s(0,5) s(-1,5) s(-2,5) s(-3,5)
Subset
sum