Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions Problem1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# https://leetcode.com/problems/coin-change/description/

# Solution 1
# TC: 2^m+n
# SC: m+n
# Did this code successfully run on Leetcode : Yes
# Any problem you faced while coding this : No
# Explored the greedy logic and realized it doesn't fit. Then decided with exhaustive approach(recursive). This approach explores all
# the permutations and combinations. We have two options at every step, choose and not choose. Whenever the amount reaches
# 0, then it means we have a valid branch. We need to check for all the branches which has amount equals to 0, then compute
# the minimum of coinsUsed and return that.

class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
self.minimum = float('inf')
self.helper(coins, amount, 0, 0)
if self.minimum == float('inf'):
return -1
return self.minimum

def helper(self, coins, amount, i, coinsUsed):

if amount < 0 or i == len(coins):
return

if amount == 0:
self.minimum = min(self.minimum, coinsUsed)
return

# case 0 // not choose
self.helper(coins, amount, i+1, coinsUsed)

# case 1 // choose
self.helper(coins, amount-coins[i], i, coinsUsed+1)

# Solution 2
# DP with tabulation using 2D matrix
# TC: O(m*n)
# SC: O(m*n)

class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:

m = len(coins)
n = amount

dp = [[0] * (n + 1) for _ in range(m+1)]

for j in range(1, n+1):
dp[0][j] = 99999

for i in range(1, m+1):
for j in range(1, n+1):
if j < coins[i-1]: # no choose is available
dp[i][j] = dp[i-1][j]
else:
# min between choose and no choose
dp[i][j] = min(dp[i-1][j], 1 + dp[i][j- coins[i-1]])

if dp[m][n] == 99999: return -1

return dp[m][n]


# Solution 3
# DP with tabulation using 1D array
# TC: O(m*n)
# SC: O(n)

class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:

m = len(coins)
n = amount

dp = [0] * (n + 1)

for j in range(1, n+1):
dp[j] = 99999

for i in range(1, m+1):
for j in range(1, n+1):
if j < coins[i-1]: # no choose is available
dp[j] = dp[j]
else:
# min between choose and no choose
dp[j] = min(dp[j], 1 + dp[j- coins[i-1]])

if dp[n] == 99999: return -1

return dp[n]


80 changes: 80 additions & 0 deletions Problem2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# https://leetcode.com/problems/house-robber/description/

# Exhaustive approach
# TC: O(2^n)
# SC: O(n)

class Solution:
highest = 0
def rob(self, nums: List[int]) -> int:
self.helper(nums, 0, 0)
return self.highest

def helper(self, nums, i, robbings):

if i >= len(nums):
self.highest = max(self.highest, robbings)
return

# case 0
self.helper(nums, i+1, robbings)

# case 1
self.helper(nums, i+2, robbings + nums[i])

# int based recursion

class Solution:
highest = 0
def rob(self, nums: List[int]) -> int:
return self.helper(nums, 0, 0)

def helper(self, nums, i, robbings):

if i >= len(nums):
return robbings

# case 0
case0 = self.helper(nums, i+1, robbings)

# case 1
case1 = self.helper(nums, i+2, robbings + nums[i])

return max(case0, case1)

# DP solution
# TC: O(n)
# SC: O(n)

class Solution:
def rob(self, nums: List[int]) -> int:
n = len(nums)
if n == 1:
return nums[0]
dp = [0] * n

dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])

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

return dp[n-1]

# Using curr and prev

class Solution:
def rob(self, nums: List[int]) -> int:
n = len(nums)
if n == 1:
return nums[0]

prev = nums[0]
curr = max(nums[0], nums[1])

for i in range(2, n):
temp = curr
curr = max(curr, nums[i] + prev)
prev = temp

return curr