Skip to content

Commit

Permalink
added some dp programs
Browse files Browse the repository at this point in the history
  • Loading branch information
glowfi committed Feb 25, 2024
1 parent a279750 commit c15a113
Show file tree
Hide file tree
Showing 21 changed files with 1,489 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# https://www.geeksforgeeks.org/problems/shortest-common-supersequence0322/1 , Medium


# Recursion
# T.C. - O(ind1*ind2*2^n)
# S.C - O(min(ind1,ind2))


class Solution:
def solve(self, i1, i2, X, Y):
if i1 == 0 or i2 == 0:
return 0

match, notMatch = 0, 0

if X[i1 - 1] == Y[i2 - 1]:
match = 1 + self.solve(i1 - 1, i2 - 1, X, Y)

else:
notMatch = max(self.solve(i1 - 1, i2, X, Y), self.solve(i1, i2 - 1, X, Y))

return max(match, notMatch)

def shortestCommonSupersequence(self, X, Y, m, n):
lcs_length = self.solve(m, n, X, Y)

return (m + n) - lcs_length


# Memoization
# T.C. - O(ind1*ind2*n)
# S.C - O(min(ind1,ind2))+O(ind1*ind2)


class Solution:
def solve(self, i1, i2, X, Y, dp):
if (i1, i2) in dp:
return dp[(i1, i2)]

if i1 == 0 or i2 == 0:
return 0

match, notMatch = 0, 0

if X[i1 - 1] == Y[i2 - 1]:
match = 1 + self.solve(i1 - 1, i2 - 1, X, Y, dp)

else:
notMatch = max(
self.solve(i1 - 1, i2, X, Y, dp), self.solve(i1, i2 - 1, X, Y, dp)
)

dp[(i1, i2)] = max(match, notMatch)

return dp[(i1, i2)]

def shortestCommonSupersequence(self, X, Y, m, n):
lcs_length = self.solve(m, n, X, Y, {})

return (m + n) - lcs_length


# Tabulation
# T.C. - O(ind1*ind2)
# S.C - O(ind1*ind2)


class Solution:
def shortestCommonSupersequence(self, X, Y, m, n):
dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)]

for i1 in range(m + 1):
for i2 in range(n + 1):
if i1 == 0 or i2 == 0:
dp[i1][i2] = 0
else:
match, notMatch = 0, 0

if X[i1 - 1] == Y[i2 - 1]:
match = 1 + dp[i1 - 1][i2 - 1]
else:
notMatch = max(dp[i1 - 1][i2], dp[i1][i2 - 1])

dp[i1][i2] = max(match, notMatch)

lcs_length = dp[m][n]

return (m + n) - lcs_length


# Space Optimized
# T.C. - O(ind1*ind2)
# S.C - O(ind2)


class Solution:
def shortestCommonSupersequence(self, X, Y, m, n):
dp = [0 for _ in range(n + 1)]

for i1 in range(m + 1):
tmp = [0 for _ in range(n + 1)]
for i2 in range(n + 1):
if i1 == 0 or i2 == 0:
tmp[i2] = 0
else:
match, notMatch = 0, 0

if X[i1 - 1] == Y[i2 - 1]:
match = 1 + dp[i2 - 1]
else:
notMatch = max(dp[i2], tmp[i2 - 1])

tmp[i2] = max(match, notMatch)
dp = tmp

lcs_length = dp[n]

return (m + n) - lcs_length
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# https://leetcode.com/problems/shortest-common-supersequence/ , Hard


# Tabulation
# T.C. - O(m*m)+O(n*m)
# S.C - O(n*m)+O(k)


class Solution:
def shortestCommonSupersequence(self, str1: str, str2: str) -> str:
dp = [[0 for _ in range(len(str2) + 1)] for _ in range(len(str1) + 1)]

for i1 in range(len(str1) + 1):
for i2 in range(len(str2) + 1):
if i1 == 0 or i2 == 0:
dp[i1][i2] = 0
else:
match, notMatch = 0, 0
if str1[i1 - 1] == str2[i2 - 1]:
match = 1 + dp[i1 - 1][i2 - 1]
else:
notMatch = max(dp[i1 - 1][i2], dp[i1][i2 - 1])

dp[i1][i2] = max(match, notMatch)

i1, i2 = len(str1), len(str2)
st = ""

while i1 > 0 and i2 > 0:
if str1[i1 - 1] == str2[i2 - 1]:
st += str1[i1 - 1]
i1 -= 1
i2 -= 1
elif dp[i1 - 1][i2] > dp[i1][i2 - 1]:
st += str1[i1 - 1]
i1 -= 1
else:
st += str2[i2 - 1]
i2 -= 1

while i1 > 0:
st += str1[i1 - 1]
i1 -= 1

while i2 > 0:
st += str2[i2 - 1]
i2 -= 1

return st[::-1]
33 changes: 33 additions & 0 deletions Programs/9_DynamicProgramming/34_Longest_Palindromic_Substring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# https://leetcode.com/problems/longest-palindromic-substring/ , Medium


# Tabulation
# T.C. - O(n^2)
# S.C - O(n^2)


class Solution:
def longestPalindrome(self, s: str) -> str:
dp = [[0 for _ in range(len(s))] for _ in range(len(s))]

res = ""
maxLen = 0

for diff in range(len(s)):
for i in range(len(s)):
j = i + diff
if j < len(s):
if i == j:
dp[i][j] = 1
elif diff == 1:
dp[i][j] = 2 if s[i] == s[j] else 0
else:
if s[i] == s[j] and dp[i + 1][j - 1]:
dp[i][j] = dp[i + 1][j - 1] + 2

if dp[i][j]:
if dp[i][j] > maxLen:
maxLen = dp[i][j]
res = s[i : i + diff + 1]

return res
119 changes: 119 additions & 0 deletions Programs/9_DynamicProgramming/35_Distinct_Subsequences.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# https://leetcode.com/problems/distinct-subsequences/ , Hard


# Recursion
# T.C. - O(2^(n*m))
# S.C - O(n+m)


class Solution:
def solve(self, i: int, j: int, s: str, t: str) -> int:
# Base Case
if j == 0:
return 1

if i == 0:
return 0

# Try out all ways
match, notMatch = 0, 0

# Match
if s[i - 1] == t[j - 1]:
match = self.solve(i - 1, j - 1, s, t) + self.solve(i - 1, j, s, t)
return match

else:
# notMatch
notMatch = self.solve(i - 1, j, s, t)
return notMatch

def numDistinct(self, s: str, t: str) -> int:
return self.solve(len(s), len(t), s, t)


# Memoization
# T.C. - O(N*M)
# S.C - O(n+m)+O(n*m)


class Solution:
def solve(self, i: int, j: int, s: str, t: str, dp: dict) -> int:
if (i, j) in dp:
return dp[(i, j)]

# Base Case
if j == 0:
return 1

if i == 0:
return 0

# Try out all ways
match, notMatch = 0, 0

# Match
if s[i - 1] == t[j - 1]:
match = self.solve(i - 1, j - 1, s, t, dp) + self.solve(i - 1, j, s, t, dp)
dp[(i, j)] = match
return dp[(i, j)]

else:
# notMatch
notMatch = self.solve(i - 1, j, s, t, dp)
dp[(i, j)] = notMatch
return dp[(i, j)]

def numDistinct(self, s: str, t: str) -> int:
return self.solve(len(s), len(t), s, t, {})


# Tabulation
# T.C. - O(N*M)
# S.C - O(n*m)


class Solution:
def numDistinct(self, s: str, t: str) -> int:
dp = [[0 for _ in range(len(t) + 1)] for _ in range(len(s) + 1)]

for i in range(len(s) + 1):
for j in range(len(t) + 1):
if j == 0:
dp[i][j] = 1
elif i == 0:
dp[i][j] = 0
else:
if s[i - 1] == t[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]
else:
dp[i][j] = dp[i - 1][j]

return dp[len(s)][len(t)]


# Space Optimized
# T.C. - O(N*M)
# S.C - O(m)+O(n)


class Solution:
def numDistinct(self, s: str, t: str) -> int:
dp = [0 for _ in range(len(t) + 1)]

for i in range(len(s) + 1):
tmp = [0 for _ in range(len(t) + 1)]
for j in range(len(t) + 1):
if j == 0:
tmp[j] = 1
elif i == 0:
tmp[j] = 0
else:
if s[i - 1] == t[j - 1]:
tmp[j] = dp[j - 1] + dp[j]
else:
tmp[j] = dp[j]

dp = tmp

return dp[len(t)]
Loading

0 comments on commit c15a113

Please sign in to comment.