Skip to content

Commit

Permalink
added DP programs
Browse files Browse the repository at this point in the history
  • Loading branch information
glowfi committed Jan 4, 2024
1 parent 157d35b commit 78bdc0c
Show file tree
Hide file tree
Showing 13 changed files with 1,157 additions and 1 deletion.
116 changes: 116 additions & 0 deletions Programs/9_Dynamic_Programming/10_Triangle_Grid_Min_Path_Sum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# https://leetcode.com/problems/triangle/ , Medium


# Recursion
# T.C. - O(N*M)
# S.C - O(N+M)


class Solution:
def solve(self, i, j, m, triangle):
if i >= m:
return float("inf")

if i == m - 1:
return triangle[m - 1][j]

# Go to ith of next row
way_1 = self.solve(i + 1, j, m, triangle) + triangle[i][j]

# Go to (i+1)th of next row
way_2 = self.solve(i + 1, j + 1, m, triangle) + triangle[i][j]

return min(way_1, way_2)

def minimumTotal(self, triangle: List[List[int]]) -> int:
m = len(triangle)
return self.solve(0, 0, m, triangle)


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


class Solution:
def solve(self, i, j, m, triangle, dp):
if i >= m:
return float("inf")

if (i, j) in dp:
return dp[(i, j)]

if i == m - 1:
return triangle[m - 1][j]

# Go to ith of next row
way_1 = self.solve(i + 1, j, m, triangle, dp) + triangle[i][j]

# Go to (i+1)th of next row
way_2 = self.solve(i + 1, j + 1, m, triangle, dp) + triangle[i][j]

dp[(i, j)] = min(way_1, way_2)

return dp[(i, j)]

def minimumTotal(self, triangle: List[List[int]]) -> int:
m = len(triangle)
dp = {}
return self.solve(0, 0, m, triangle, dp)


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


class Solution:
def minimumTotal(self, triangle: List[List[int]]) -> int:
m = len(triangle)

dp = [[0 for _ in range(len(triangle[i]))] for i in range(m)]

for i in range(len(triangle[-1])):
dp[m - 1][i] = triangle[m - 1][i]

for i in range(m - 2, -1, -1):
for j in range(0, len(triangle[i])):
way_1, way_2 = float("inf"), float("inf")

if i + 1 < m:
way_1 = triangle[i][j] + dp[i + 1][j]
way_2 = triangle[i][j] + dp[i + 1][j + 1]

dp[i][j] = min(way_1, way_2)

return dp[0][0]


# Space Optimized
# T.C. - O(N*M)
# S.C - O(col_length_last_row)


class Solution:
def minimumTotal(self, triangle: List[List[int]]) -> int:
m = len(triangle)

mx_col_length = len(triangle[-1])
dp = [-1 for _ in range(mx_col_length)]

for i in range(len(triangle[-1])):
dp[i] = triangle[m - 1][i]

for i in range(m - 2, -1, -1):
tmp = [-1 for _ in range(len(triangle[i]))]
for j in range(0, len(triangle[i])):
way_1, way_2 = float("inf"), float("inf")

if i + 1 < m:
way_1 = triangle[i][j] + dp[j]
way_2 = triangle[i][j] + dp[j + 1]

tmp[j] = min(way_1, way_2)
dp = tmp

return dp[0]
86 changes: 86 additions & 0 deletions Programs/9_Dynamic_Programming/1_Fibonacci.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# https://leetcode.com/problems/fibonacci-number/ , Easy

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


class Solution:
def solve(self, n):
# Base
if n <= 1:
return n
# Hypo
prev = self.solve(n - 1)
prev_prev = self.solve(n - 2)

# Induction
return prev + prev_prev

def fib(self, n: int) -> int:
return self.solve(n)


# Memoization
# T.C. - O(n)
# S.C - O(n) + O(n)


class Solution:
def solve(self, n, dp):
# Base
if n <= 1:
return n

if n in dp:
return dp[n]

# Hypo
prev = self.solve(n - 1, dp)
prev_prev = self.solve(n - 2, dp)

dp[n] = prev_prev + prev

# Induction
return dp[n]

def fib(self, n: int) -> int:
dp = {}
return self.solve(n, dp)


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


class Solution:
def fib(self, n: int) -> int:
dp = {i: 0 for i in range(n + 1)}
dp[0] = 0
dp[1] = 1

for i in range(2, n + 1):
dp[i] = dp[i - 1] + dp[i - 2]

return dp[n]


# Space Optimized
# T.C. - O(n)
# S.C - O(1)


class Solution:
def fib(self, n: int) -> int:
if n == 0 or n == 1:
return n
prev_prev = 0
prev = 1

for i in range(2, n + 1):
curr = prev + prev_prev
prev_prev = prev
prev = curr

return prev
88 changes: 88 additions & 0 deletions Programs/9_Dynamic_Programming/2_Climbing_Stairs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# https://leetcode.com/problems/climbing-stairs/ , Easy


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


class Solution:
def solve(self, n):
if n == 0:
return 1

c = 0

for i in range(1, 2 + 1):
if n - i >= 0:
c += self.solve(n - i)

return c

def climbStairs(self, n: int) -> int:
return self.solve(n)


# Memoization
# T.C. - O(n)
# S.C - O(n)+O(n)


class Solution:
def solve(self, n, dp):
if n == 0:
return 1

if n in dp:
return dp[n]

c = 0

for i in range(1, 2 + 1):
if n - i >= 0:
c += self.solve(n - i, dp)

dp[n] = c

return dp[n]

def climbStairs(self, n: int) -> int:
dp = {}
return self.solve(n, dp)


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


class Solution:
def climbStairs(self, n: int) -> int:
dp = {i: 0 for i in range(n + 1)}
dp[0] = 1
dp[1] = 1

for i in range(2, n + 1):
dp[i] = dp[i - 1] + dp[i - 2]

return dp[n]


# Space Optimized
# T.C. - O(n)
# S.C - O(1)


class Solution:
def climbStairs(self, n: int) -> int:
if n <= 1:
return 1
prev_prev = 1
prev = 1

for i in range(2, n + 1):
curr = prev + prev_prev
prev_prev = prev
prev = curr

return prev
92 changes: 92 additions & 0 deletions Programs/9_Dynamic_Programming/3_Geek_Jump.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# https://www.geeksforgeeks.org/problems/geek-jump/1 , Easy

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


from types import prepare_class


class Solution:
def solve(self, n, height, k):
if n == 0:
return 0

min_energy = float("inf")

for step in range(1, k + 1):
if n - step >= 0:
val = self.solve(n - step, height, k)
if val + abs(height[n] - height[n - step]) < min_energy:
min_energy = val + abs(height[n] - height[n - step])

return min_energy

def minimumEnergy(self, height, n):
k = 2
return self.solve(n - 1, height, k)


# Memoization
# T.C. - O(n)
# S.C - O(n)+O(n)


class Solution:
def solve(self, n, height, dp, k):
if n == 0:
return 0

if n in dp:
return dp[n]

min_energy = float("inf")

for step in range(1, k + 1):
if n - step >= 0:
val = self.solve(n - step, height, dp, k)
if val + abs(height[n] - height[n - step]) < min_energy:
min_energy = val + abs(height[n] - height[n - step])

dp[n] = min_energy

return dp[n]

def minimumEnergy(self, height, n):
dp = {}
k = 2
return self.solve(n - 1, height, dp, k)


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


class Solution:
def minimumEnergy(self, height, n):
dp = {i: 0 for i in range(n)}
dp[0] = 0
k = 2

for i in range(1, n):
min_energy = float("inf")
for step in range(1, k + 1):
if i - step >= 0:
val = dp[i - step]
min_energy = min(
val + abs(height[i] - height[i - step]), min_energy
)
dp[i] = min_energy

return dp[n - 1]


n = 4
height = [10, 20, 30, 10]

n = 8
height = [7, 4, 4, 2, 6, 6, 3, 4]
obj = Solution()
print(obj.minimumEnergy(height, n))
Loading

0 comments on commit 78bdc0c

Please sign in to comment.