Scs
Scs
common
supersequenc
A subsequence
of a string is a
subset of its
characters,
that are not
rai
necessarily
adjacent but
is a
subsequence n
of
have to be in
the right order
programming
A subsequence
of a string is a
subset of its
characters,
that are not
rai
necessarily
adjacent but
is a
subsequence n is a
supersequence
of of
have to be in
the right order
programming
Given two
strings and ,
find the length
of their
shortest
common
supersequence
Given two strings and , find
the length of their shortest
common supersequence
input:
s1 = "abdacbab"
abdacbab
s2 = "acebfca"
output: 11 abdacebfcab
explanation: the scs of
s1 and s2 is
"abdacebfcab", its acebfca
length is 11
abdacbab acebfca
abdacbabacebfca
a
abdacbab
bdacbab a
acebfca
c e bf c a
abdacbabacebfca
abdacbab acebfca
abdacbab acebfca
𝑠𝑐𝑠 ( ab , bc ) → abc
input:
s1 =
"abecd"
s2 =
"afcbd"
s1 abecd
:
s2: afcbd
input:
s1 =
"abecd"
s2 =
"afcbd"
s1 abecd Error
: s2 is not a
s2: afcbd subsequence
of scs
scs: afbecd
input:
s1 =
"abecd"
s2 = Error
"afcbd" s1 is not a
s1 abecd subsequence
of scs
:
s2: afcbd
scs: afcebd
"abdacbab
"
Longest "acebfca"
common
subsequenc
input:
s1 = 𝑙𝑐𝑠 ( abecd , afcbd ) → abd
"abecd"
s2 =
"afcbd"
s1 abecd
:
s2: afcbd
input:
s1 = 𝑙𝑐𝑠 ( abecd , afcbd ) → abd
"abecd"
s2 =
"afcbd"
s1 abecd
:
s2: afcbd
scs: afcbecd
input:
𝑙𝑐𝑠 ( abdacbab , acebfca ) → acba
s1 =
"abdacbab"
s2 = "acebfca"
s1 abdacbab
:
s2: acebfca
input:
𝑙𝑐𝑠 ( abdacbab , acebfca ) → acba
s1 =
"abdacbab"
s2 = "acebfca"
s1 abdacbab
:
s2: acebfca
scs: abdacebfcab
|𝑠𝑐𝑠 ( 𝑠 1 , 𝑠 2 )|=|𝑠 1|+|𝑠 2|−∨𝑙𝑐𝑠 ( 𝑠 1 , 𝑠 2 )∨¿
def scs(s1, s2):
return len(s1) + len(s2) - lcs(s1, s2)
input:
s1 = s1: abdacbab
"abdacbab" s2: acebfca
s2 = "acebfca" scs(0,0 scs:
)
input:
s1 = s1: abdacbab
"abdacbab" s2: acebfca
s2 = "acebfca" scs(0,0 scs: a
)
scs(1,1
)
input:
s1 = s1: abdacbab
"abdacbab" s2: acebfca
s2 = "acebfca" scs(0,0 scs: a
)
scs(1,1
)
input:
s1 =
"abdacbab"
s2 = "acebfca"
s1 abdacbab
:
s2: acebfca
input:
s1 =
"abdacbab"
s2 = "acebfca"
s1 abdacbab
:
s2: acebfca
input:
s1 = s1: abdacbab
"abdacbab" s2: acebfca
s2 = "acebfca" scs(0,0 scs: a
)
scs(1,1
)
scs(2,1 scs(1,2
) )
0 𝑖𝑓 𝑖=|𝑠1|
0 𝑖𝑓 𝑗=¿ 𝑠2 ∨¿
s1: abdacbab
s2: acebfca
j
𝑖=|𝑠 1|→ 𝑠𝑐𝑠 ( 𝑠 1 , 𝑠 2 ) =𝑙𝑒𝑛 ( 𝑠 2 ) − 𝑗
i
s1: abdacbab
s2: acebfca
j
s1: abdacbab
s2: acebfca
j
|𝑠 2|− 𝑗 𝑖𝑓 𝑖=|𝑠1|
|𝑠1|− 𝑖 𝑖𝑓 𝑗=¿ 𝑠2 ∨¿
𝑠 𝑐𝑠 ( 𝑖 , 𝑗 )=¿
1+ 𝑠𝑐𝑠( 𝑖+1 , 𝑗 +1) 𝑖𝑓 𝑠1 [ 𝑖 ] = 𝑠2 [ 𝑗 ]
|𝑠 2|− 𝑗 𝑖𝑓 𝑖=|𝑠1|
|𝑠1|− 𝑖 𝑖𝑓 𝑗=¿ 𝑠2 ∨¿
𝑠𝑐𝑠 ( 𝑖 , 𝑗 )=¿
1+ 𝑠𝑐𝑠( 𝑖+1 , 𝑗 +1) 𝑖𝑓 𝑠1 [ 𝑖 ] = 𝑠2 [ 𝑗 ]
lcs:
0 𝑖𝑓 𝑗=¿ 𝑠2 ∨¿
𝑙𝑐𝑠 ( 𝑖 , 𝑗 )=¿
1+𝑙𝑐𝑠 (𝑖+1 , 𝑗+1) 𝑖𝑓 𝑠1 [ 𝑖 ] = 𝑠2 [ 𝑗 ]
|𝑠 2|− 𝑗 𝑖𝑓 𝑖=|𝑠1|
scs
|𝑠1|− 𝑖 𝑖𝑓 𝑗=¿ 𝑠2 ∨¿
𝑠𝑐𝑠 ( 𝑖 , 𝑗 )=¿
1+ 𝑠𝑐𝑠( 𝑖+1 , 𝑗 +1) 𝑖𝑓 𝑠1 [ 𝑖 ] = 𝑠2 [ 𝑗 ]
lcs:
0 𝑖𝑓 𝑗=¿ 𝑠2 ∨¿
𝑙𝑐𝑠 ( 𝑖 , 𝑗 )=¿
1+𝑙𝑐𝑠 (𝑖+1 , 𝑗+1) 𝑖𝑓 𝑠1 [ 𝑖 ] = 𝑠2 [ 𝑗 ]
|𝑠 2|− 𝑗 𝑖𝑓 𝑖=|𝑠1|
scs
|𝑠1|− 𝑖 𝑖𝑓 𝑗=¿ 𝑠2 ∨¿
𝑠𝑐𝑠 ( 𝑖 , 𝑗 )=¿
1+ 𝑠𝑐𝑠( 𝑖+1 , 𝑗 +1) 𝑖𝑓 𝑠1 [ 𝑖 ] = 𝑠2 [ 𝑗 ]
𝑇 ( 𝑛,𝑚 ) =𝑂 ( 2 ) 𝑛+𝑚
1
def scs(s1, s2, i=0, j=0, lookup=None):
lookup
2 = {} if lookup is None else lookup
if (i, j) in lookup:
3 return lookup[(i, j)]
if i == len(s1):
return len(s2)-j
elif j == len(s2):
return len(s1)-i
elif s1[i] == s2[j]:
lookup[(i, j)] = 1 + scs(s1, s2, i+1, j+1, lookup)
4
return lookup[(i, j)]
else:
lookup[(i, j)] = 1 + min(scs(s1, s2, i+1, j, lookup),
scs(s1, s2, i, j+1, lookup))
return lookup[(i, j)]
Memoization
solution:
𝑇 ( 𝑛,𝑚) =𝑂(𝑛𝑚)
lcs
𝑚+1
𝑛+1
lcs scs
𝑚+1 𝑚+1
𝑛+1 𝑛+1
lcs scs
𝑚+1 𝑚+1
0 0 0 0 0 0 0 0
0
0
0 ¿ 𝑙𝑐𝑠 ( , 𝑠 )∨¿ 0
𝑛+1 0 𝑛+1
0
0
0
0
lcs scs
𝑚+1 𝑚+1
0 0 0 0 0 0 0 0
0
0
0 ( , 𝑠 ) ∨¿∨𝑠∨¿
¿ 𝑠𝑐𝑠
𝑛+1 0 𝑛+1
0
0
0
0
lcs scs
𝑚+1 𝑚+1
0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7
0 1
0 2
0 ( , 𝑠 ) ∨¿∨𝑠∨¿
¿ 𝑠𝑐𝑠 3
𝑛+1 0 𝑛+1 4
0 5
0 6
0 7
0 8
lcs scs
def lcs(s1, s2): def scs(s1, s2):
n, m = len(s1), len(s2) n, m = len(s1), len(s2)
dp = [[0]*(m+1) for i in range(n+1)] dp = [[0]*(m+1) for i in range(n+1)]
for j in range(1, m+1): for j in range(1, m+1):
dp[0][j] = 0 dp[0][j] = j
for i in range(1, n+1): for i in range(1, n+1):
dp[i][0] = 0 dp[i][0] = i
for i in range(1, n+1): for i in range(1, n+1):
for j in range(1, m+1): for j in range(1, m+1):
if s1[i-1] == s2[j-1]: if s1[i-1] == s2[j-1]:
dp[i][j] = 1 + dp[i-1][j-1] dp[i][j] = 1 + dp[i-1][j-1]
else: else:
dp[i][j] = max(dp[i-1][j], dp[i][j] = 1 + min(dp[i-1][j],
dp[i][j-1]) dp[i][j-1])
return dp[n][m] return dp[n][m]
input:
s1 = a c e b f c a
"abdacbab"
0 1 2 3 4 5 6 7
s2 = "acebfca"
a 1 1 2 3 4 5 6 7
def scs(s1, s2):
n, m = len(s1), len(s2) b 2 2 3 4 4 5 6 7
dp = [[0]*(m+1) for i in range(n+1)]
for j in range(1, m+1): d 3 3 4 5 5 6 7 8
dp[0][j] = j
for i in range(1, n+1): a 4 4 5 6 6 7 8 8
dp[i][0] = i
for i in range(1, n+1): c 5 5 5 6 7 8 8 9
for j in range(1, m+1):
b 6 1
if s1[i-1] == s2[j-1]: 6 6 7 7 8 9
0
dp[i][j] = 1 + dp[i-1][j-1] 1 1
a 7 7 7 8 8 9
else: 0 0
dp[i][j] = 1 + min(dp[i-1][j], b 8 1 1 1
8 8 9 9
dp[i][j-1]) 0 1 1
return dp[n][m]
input:
s1 = a c e b f c a
"abdacbab"
0 1 2 3 4 5 6 7
s2 = "acebfca"
a 1 1 2 3 4 5 6 7
def scs(s1, s2):
n, m = len(s1), len(s2) b 2 2 3 4 4 5 6 7
dp = [[0]*(m+1) for i in range(n+1)]
for j in range(1, m+1): d 3 3 4 5 5 6 7 8
dp[0][j] = j
for i in range(1, n+1): a 4 4 5 6 6 7 8 8
dp[i][0] = i
for i in range(1, n+1): c 5 5 5 6 7 8 8 9
for j in range(1, m+1):
b 6 1
if s1[i-1] == s2[j-1]: 6 6 7 7 8 9
0
dp[i][j] = 1 + dp[i-1][j-1] 1 1
a 7 7 7 8 8 9
else: 0 0
dp[i][j] = 1 + min(dp[i-1][j], b 8 1 1 1
8 8 9 9
dp[i][j-1]) 0 1 1
return dp[n][m]
Tabulation
solution:
𝑇 ( 𝑛,𝑚) =𝑂(𝑛𝑚)
Space-optimized
tabulation
solution:
𝑇 ( 𝑛,𝑚) =𝑂(𝑛𝑚)
Shortest
common
supersequenc