0% found this document useful (0 votes)
5 views71 pages

Subset Sum

The document discusses the problem of counting subsets of a given array of strictly positive integers that sum up to a specified integer k. It provides an example with the array [1, 2, 3, 1, 4] and k=6, resulting in four valid subsets. The document also outlines a recursive approach to solve the problem, including base cases and recursive calls.

Uploaded by

cs1221097
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views71 pages

Subset Sum

The document discusses the problem of counting subsets of a given array of strictly positive integers that sum up to a specified integer k. It provides an example with the array [1, 2, 3, 1, 4] and k=6, resulting in four valid subsets. The document also outlines a recursive approach to solve the problem, including base cases and recursive calls.

Uploaded by

cs1221097
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 71

Subset

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

𝑠𝑢𝑏𝑠𝑒𝑡𝑠 ( 𝑘, 𝑖 )=¿ 0 𝑖𝑓 𝑖=|𝑎𝑟𝑟 |𝑜𝑟 𝑘< 0

𝑠𝑢𝑏𝑠𝑒𝑡𝑠 ( 𝑘−𝑎𝑟𝑟 [ 𝑖 ] ,𝑖+1 ) 𝑜𝑡h𝑒𝑟𝑤𝑖𝑠𝑒


input:
arr = [1, 2, 3, 1, 4],
k=6

[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

𝑠𝑢𝑏𝑠𝑒𝑡𝑠 ( 𝑘, 𝑖 )=¿ 0 𝑖𝑓 𝑖=|𝑎𝑟𝑟 |𝑜𝑟 𝑘< 0

𝑠𝑢𝑏𝑠𝑒𝑡𝑠 ( 𝑘−𝑎𝑟𝑟 [ 𝑖 ] ,𝑖+1 ) 𝑜𝑡h𝑒𝑟𝑤𝑖𝑠𝑒


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

𝑠𝑢𝑏𝑠𝑒𝑡𝑠 ( 𝑘, 𝑖 )=¿ 0 𝑖𝑓 𝑖=|𝑎𝑟𝑟 |𝑜𝑟 𝑘< 0

𝑠𝑢𝑏𝑠𝑒𝑡𝑠 ( 𝑘−𝑎𝑟𝑟 [ 𝑖 ] ,𝑖+1 ) 𝑜𝑡h𝑒𝑟𝑤𝑖𝑠𝑒


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)

.
.
.

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,2) s(5,2) s(4,2) s(3,2)

s(6,3) s(5,3) s(4,3) s(3,3) s(2,3) s(1,3) s(0,3)

s(6,4) s(5,4) s(4,4) s(3,4) s(2,4) s(1,4) s(0,4)

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,2) s(5,2) s(4,2) s(3,2)

s(6,3) s(5,3) s(4,3) s(3,3) s(2,3) s(1,3) s(0,3)

s(6,4) s(5,4) s(4,4) s(3,4) s(2,4) s(1,4) s(0,4)

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 ) ∗ 𝑂 (1 )=𝑂 (𝑛𝑘)


𝑆 ( 𝑛 , 𝑘 )=𝑂 ( 𝑛 ) + 𝑂 ( 𝑛𝑘 )=𝑂 (𝑛𝑘)
call stack lookup
size table
size
𝑖 ∈{0 , 1 , … ,𝑛 − 1} 𝑘∈ {𝑘0 , 𝑘0 −1 , … , 0 }
𝑛 𝑘 +1
𝑘 +1

𝑛
𝑘 +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

dp[i][j] represents the


number of subsets that
sum up to j in the part of
arr from 0 to i inclusive
input:
0 1 2 3 4 5 6
arr = [1, 2, 3,
1, 4], 0
k=6
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

if we don't take the last element, dp[i][j] is dp[i-1][j]


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 if we take the arr = [1, 2, 3, [1, 1]
and
last element
1], [2]
k=2
if we don't take the last element, dp[i][j] is dp[i-1][j]
if we take the last element, dp[i][j] is dp[i-1][j-arr[i]]
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 if we take the arr = [1, 2, 3, [1, 1]
and
last element
1], [2]
k=2
if we don't take the last element, dp[i][j] is dp[i-1][j]
if we take the last element, dp[i][j] is dp[i-1][j-arr[i]]
we want to get subsets of both cases,
so dp[i][j] is dp[i-1][j] + dp[i-1][j-arr[i]] (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

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,2) s(5,2) s(4,2) s(3,2)

s(6,3) s(5,3) s(4,3) s(3,3) s(2,3) s(1,3) s(0,3)

s(6,4) s(5,4) s(4,4) s(3,4) s(2,4) s(1,4) s(0,4)

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

You might also like