Skip to content

Commit 4a37872

Browse files
Meto TrajkovskiMeto Trajkovski
authored andcommitted
Added solutions for interleaving strings
1 parent 4d5fe57 commit 4a37872

1 file changed

Lines changed: 106 additions & 0 deletions

File tree

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
'''
2+
Interleaving Strings
3+
4+
Given are three strings A, B and C.
5+
C is said to be interleaving of A and B, if:
6+
- it contains all characters of A and B, and
7+
- order of all characters from A and B is preserved in C
8+
Your task is to count in how many ways C can be formed by interleaving of A and B.
9+
10+
Input: A='xy', B= 'xz', C: 'xxyz'
11+
Output: 2
12+
Output explanation:
13+
1) Take 'x' from A, then 'x' from B, then 'y' from A and at the end 'z' from B.
14+
2) Take 'x' from B, then 'x' from A, then 'y' from A and at the end 'z' from B.
15+
16+
=========================================
17+
2D Dynamic programming solution.
18+
Time Complexity: O(N*M)
19+
Space Complexity: O(N*M)
20+
1D Dynamic programming solution. Only the last two rows from the whole matrix are used, but that could be represented using only 1 row.
21+
Time Complexity: O(N*M)
22+
Space Complexity: O(M)
23+
'''
24+
25+
##############
26+
# Solution 1 #
27+
##############
28+
29+
def interleaving_strings_1(A, B, C):
30+
nA, nB, nC = len(A), len(B), len(C)
31+
if nA + nB != nC:
32+
return 0
33+
34+
dp = [[0 for j in range(nB + 1)] for i in range(nA + 1)]
35+
36+
# starting values
37+
dp[0][0] = 1
38+
39+
for i in range(1, nA + 1):
40+
if A[i - 1] == C[i - 1]:
41+
# short form of if A[i - 1] == C[i - 1] and dp[i - 1][0] == 1
42+
# dp[i][0] and dp[0][1] can be only 0 or 1
43+
dp[i][0] = dp[i - 1][0]
44+
45+
for i in range(1, nB + 1):
46+
if B[i - 1] == C[i - 1]:
47+
dp[0][i] = dp[0][i - 1]
48+
49+
# run dp
50+
for i in range(1, nA + 1):
51+
for j in range(1, nB + 1):
52+
if A[i - 1] == C[i + j - 1]:
53+
# look for the dp value from the previous position
54+
dp[i][j] += dp[i - 1][j]
55+
if B[j - 1] == C[i + j - 1]:
56+
# look for the dp value from the previous position
57+
dp[i][j] += dp[i][j - 1]
58+
59+
return dp[nA][nB]
60+
61+
62+
##############
63+
# Solution 2 #
64+
##############
65+
66+
def interleaving_strings_2(A, B, C):
67+
nA, nB, nC = len(A), len(B), len(C)
68+
if nA + nB != nC:
69+
return 0
70+
71+
dp = [0 for j in range(nB + 1)]
72+
73+
# starting values
74+
dp[0] = 1
75+
76+
for i in range(1, nB + 1):
77+
if B[i - 1] == C[i - 1]:
78+
dp[i] = dp[i - 1]
79+
80+
# run dp
81+
for i in range(1, nA + 1):
82+
if A[i - 1] != C[i - 1]:
83+
# reset the value
84+
dp[0] = 0
85+
86+
for j in range(1, nB + 1):
87+
if A[i - 1] != C[i + j - 1]:
88+
# reset the value
89+
dp[j] = 0
90+
if B[j - 1] == C[i + j - 1]:
91+
dp[j] += dp[j - 1]
92+
93+
return dp[nB]
94+
95+
96+
###########
97+
# Testing #
98+
###########
99+
100+
# Test 1
101+
# Correct result => 2
102+
print(interleaving_strings_1('xy', 'xz', 'xxyz'))
103+
104+
# Test 2
105+
# Correct result => 2
106+
print(interleaving_strings_2('xy', 'xz', 'xxyz'))

0 commit comments

Comments
 (0)