0% found this document useful (0 votes)
3 views

Dynamic-programming

Dynamic-programming _notes

Uploaded by

Anshul Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Dynamic-programming

Dynamic-programming _notes

Uploaded by

Anshul Kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

dynamic-programming

October 29, 2024

0.1 Climbing-stairs
You are climbing a staircase. It takes n steps to reach the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Example 1: Input: n = 2 Output: 2
Explanation: There are two ways to climb to the top. 1. 1 step + 1 step 2. 2 steps
[ ]: class Solution:
def climbStairs(self, n: int) -> int:
def climbStairs_helperTD(n):
if n <= 0:
return 0
elif n == 1 or n ==2:
return n
return climbStairs_helperTD(n-1) + climbStairs_helperTD(n-2)
#return climbStairs_helperTD(n)

def climbStairs_helperBU(n):
if n <= 0:
return 0
elif n == 1 or n ==2:
return n

res = [0]*(n+1)
res[1], res[2] = 1,2
for i in range(3, n+1):
res[i] = res[i-1] + res[i-2]
return res[n]
return climbStairs_helperBU(n)

0.2 Coin-change
You are given an integer array coins representing coins of different denominations and an integer
amount representing a total amount of money.
Return the fewest number of coins that you need to make up that amount. If that amount of money
cannot be made up by any combination of the coins, return -1.

1
You may assume that you have an infinite number of each kind of coin.
Example 1:
Input: coins = [1,2,5], amount = 11 Output: 3 Explanation: 11 = 5 + 5 + 1 Example 2:
Input: coins = [2], amount = 3 Output: -1 Example 3:
Input: coins = [1], amount = 0 Output: 0

[ ]: class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
def coinChange_helperTD(n, amount):
if amount == 0:
return 0
if amount < 0 or n < 0:
return 10^7+9
else:
c1_includes = 1 + coinChange_helperTD(n, amount - coins[n-1])
c2_excludes = 0 + coinChange_helperTD(n-1, amount)
return min(c1_includes, c2_excludes)

# answer = coinChange_helperTD(n, amount)


# if answer == 10^7+9:
# return -1
# else:
# return answer

n = len(coins)
coins.sort(reverse = True)
dp = {}
print(coins)
max_size = float('Inf')
def coinChange_helperBU(n, amount):
if amount == 0:
return 0
elif n == 0:
return max_size
elif (n, amount) in dp:
return dp[(n, amount)]
else:
if coins[n-1] <= amount:
c1 = 1 + coinChange_helperBU(n, amount - coins[n-1])
c2 = coinChange_helperBU(n-1, amount)
dp[(n, amount)] = min(c1, c2)
else:
dp[(n, amount)] = max_size

return dp[(n, amount)]

2
# Main Code
answer = coinChange_helperBU(n, amount)
if answer >= max_size:
return -1
else:
return answer

0.3 Longest-increasing-subsequence
Given an integer array nums, return the length of the longest strictly increasing subsequence .
Example 1:
Input: nums = [10,9,2,5,3,7,101,18] Output: 4 Explanation: The longest increasing subsequence is
[2,3,7,101], therefore the length is 4. Example 2:
Input: nums = [0,1,0,3,2,3] Output: 4

[ ]: class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
n = len(nums)-1
def lengthOfLIS_TD(nums, n):

max_len = 1
dp = [1]*(len(nums))
for i in range(len(nums)):
for j in range(i+1):
if nums[j] < nums[i]:
dp[i] = max(dp[i], dp[j]+1)
max_len = max(max_len, dp[i])
print(dp)
return max_len
return lengthOfLIS_TD(nums, n-1)

li = None
n = len(nums)-1
dp = {}
def lengthOfLIS_helperBU(nums, n, li):
if n < 0:
return 0
if (n, li) in dp:
return dp[(n,li)]
else:
if li is None or nums[n] < nums[li]:
c1_include = 1+lengthOfLIS_helperBU(nums, n-1, n)
c2_exclude = lengthOfLIS_helperBU(nums, n-1, li)
c = max(c1_include, c2_exclude)
else:

3
c = lengthOfLIS_helperBU(nums, n-1, li)
dp[(n,li)] = c
return dp[(n,li)]
return lengthOfLIS_helperBU(nums, n, None)

0.4 Longest-common-subsequence
Given two strings text1 and text2, return the length of their longest common subsequence. If there
is no common subsequence, return 0.
A subsequence of a string is a new string generated from the original string with some characters
(can be none) deleted without changing the relative order of the remaining characters.
For example, “ace” is a subsequence of “abcde”. A common subsequence of two strings is a subse-
quence that is common to both strings.
Example 1:
Input: text1 = “abcde”, text2 = “ace” Output: 3
Explanation: The longest common subsequence is “ace” and its length is 3. Example 2:
Input: text1 = “abc”, text2 = “abc” Output: 3 Explanation: The longest common subsequence is
“abc” and its length is 3.
[ ]: class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
m = len(text1)-1
n = len(text2)-1

def longestCommonSubsequence_helper_BU(text1, text2, m, n):


if m < 0 or n < 0:
return 0
if text1[m] == text2[n]:
c1 = 1+ longestCommonSubsequence_helper_BU(text1, text2, m-1,␣
↪ n-1)
ans = c1
else:
c2 = longestCommonSubsequence_helper_BU(text1, text2, m, n-1)
c3 = longestCommonSubsequence_helper_BU(text1, text2, m-1, n)
ans = max(c2, c3)
return ans
return longestCommonSubsequence_helper_BU(text1, text2, m, n)


↪ #*******************************************************************************************
m = len(text1)
n = len(text2)
def longestCommonSubsequence_helper_TD(text1, text2, m, n):

4
dp = [[0]*(n+1) for i in range(m+1)]
for i in range(1, m+1):
for j in range(1, n+1):
if text1[i-1] == text2[j-1]:
dp[i][j] = 1 + dp[i-1][j-1]
else:
dp[i][j] = max(dp[i][j-1], dp[i-1][j])
return dp[m][n]

return longestCommonSubsequence_helper_TD(text1, text2, m, n)

0.5 Word-break
Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a
space-separated sequence of one or more dictionary words.
Note that the same word in the dictionary may be reused multiple times in the segmentation.
Example 1:
Input: s = “leetcode”, wordDict = [“leet”,“code”] Output: true Explanation: Return true because
“leetcode” can be segmented as “leet code”. Example 2:
Input: s = “applepenapple”, wordDict = [“apple”,“pen”] Output: true Explanation: Return true
because “applepenapple” can be segmented as “apple pen apple”. Note that you are allowed to
reuse a dictionary word.
[ ]: class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
def wordBreak_helper2(s, wordDict, li):
if li == 0:
return True
else:
for word_i in wordDict:
word_i_len = len(word_i)
if li >= word_i_len and s[li - word_i_len : li] == word_i:
return wordBreak_helper(s, wordDict, li-word_i_len)
return False

# li = len(s)
# return wordBreak_helper(s, wordDict, li)
##################### Methode 2######################################
# you can pick from start and slicing is the grrete idea instead of␣
↪ above
# if wordBreak_helper(s, wordDict, li - word_i_len):
# return True
def wordBreak_helper(s, wordDict):
if s== "":
return True

5
else:
for word in wordDict:
n = len(s)
li = len(word)
if li <= n and s[:li] == word:
if wordBreak_helper(s[li:], wordDict):
return True
return False
#return wordBreak_helper(s, wordDict)
def wordBreak_helper_TD(s, wordDict):
if len(s) == 0:
return True

n = len(s)
dp = [False]*(n+1)
dp[0] = True
for i in range(1, n+1): # always start from 1 becouse we filled for␣
↪ 0
for word in wordDict:
word_l = len(word)
if word_l <= i and s[i-word_l:i] == word:
dp[i] = dp[i] or dp[i-word_l]
return dp[n]
return wordBreak_helper_TD(s, wordDict)

0.6 Combination-sum-iv
Given an array of distinct integers nums and a target integer target, return the number of possible
combinations that add up to target.
The test cases are generated so that the answer can fit in a 32-bit integer.
Example 1:
Input: nums = [1,2,3], target = 4 Output: 7 Explanation: The possible combination ways are: (1,
1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) (3, 1) Note that different sequences are counted as
different combinations.
Example 2:
Input: nums = [9], target = 3 Output: 0

[ ]: class Solution:
def combinationSum4(self, nums: List[int], target: int) -> int:
##Below code is combination But we need to write the all the permutation
n = len(nums)-1
def combinationSum4_helper(n, target):
if target < 0 or n < 0:
return 0
if target == 0:

6
return 1
else:
c_include = combinationSum4_helper(n, target - nums[n])
c_exclude = combinationSum4_helper(n-1, target)
return c_include + c_exclude

↪#*******************************************************************************************
n = len(nums)-1
return combinationSum4_helper(n, target)
dp = { 0:1 }
for i in range(1, target+1):
dp[i] = 0
for num in nums:
dp[i] = dp[i] + dp.get(i - num, 0)
return dp[target]
#************************************************** TD Approach␣
↪*************************************************************#

dp = [0]*(target+1)
dp[0] = 1
for i in range(1,target+1):
for num in nums:
if num <= i:
dp[i] += dp[i - num]

return dp[target]

0.7 House-robber
You are a professional robber planning to rob houses along a street. Each house has a certain
amount of money stashed, the only constraint stopping you from robbing each of them is that
adjacent houses have security systems connected and it will automatically contact the police if two
adjacent houses were broken into on the same night.
Given an integer array nums representing the amount of money of each house, return the maximum
amount of money you can rob tonight without alerting the police.
Example 1:
Input: nums = [1,2,3,1] Output: 4 Explanation: Rob house 1 (money = 1) and then rob house 3
(money = 3). Total amount you can rob = 1 + 3 = 4.
Example 2:
Input: nums = [2,7,9,3,1] Output: 12 Explanation: Rob house 1 (money = 2), rob house 3 (money
= 9) and rob house 5 (money = 1). Total amount you can rob = 2 + 9 + 1 = 12.

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

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

0.8 House-robber-ii
You are a professional robber planning to rob houses along a street. Each house has a certain
amount of money stashed. All houses at this place are arranged in a circle. That means the first
house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected,
and it will automatically contact the police if two adjacent houses were broken into on the same
night.
Given an integer array nums representing the amount of money of each house, return the maximum
amount of money you can rob tonight without alerting the police.
Example 1:
Input: nums = [2,3,2] Output: 3 Explanation: You cannot rob house 1 (money = 2) and then rob
house 3 (money = 2), because they are adjacent houses.
Example 2:
Input: nums = [1,2,3,1] Output: 4 Explanation: Rob house 1 (money = 1) and then rob house 3
(money = 3). Total amount you can rob = 1 + 3 = 4.

[ ]: class Solution:
def rob(self, nums: List[int]) -> int:
def rob_helper_one(nums1):
n = len(nums1)

if n == 0:
return 0
if n == 1:
return nums1[0]

dp = [0]*(n+1)
dp[1] = nums1[0]
for i in range(2, n+1):
dp[i] = max( nums1[i-1]+dp[i-2], dp[i-1])
return dp[n]

n = len(nums)
if n == 0:
return 0
if n == 1:
return nums[0]
c1 = rob_helper_one(nums[:-1])
c2 = rob_helper_one(nums[1:])

8
return max(c1, c2)

0.9 Decode-ways
You have intercepted a secret message encoded as a string of numbers. The message is decoded via
the following mapping:
“1” -> ‘A’
“2” -> ‘B’

“25” -> ‘Y’
“26” -> ‘Z’
However, while decoding the message, you realize that there are many different ways you can decode
the message because some codes are contained in other codes (“2” and “5” vs “25”).
For example, “11106” can be decoded into:
“AAJF” with the grouping (1, 1, 10, 6) “KJF” with the grouping (11, 10, 6) The grouping (1, 11,
06) is invalid because “06” is not a valid code (only “6” is valid). Note: there may be strings that
are impossible to decode.
Given a string s containing only digits, return the number of ways to decode it. If the entire string
cannot be decoded in any valid way, return 0. The test cases are generated so that the answer fits
in a 32-bit integer.
Example 1:
Input: s = “12” Output: 2 Explanation: “12” could be decoded as “AB” (1 2) or “L” (12).
Example 2:
Input: s = “226” Output: 3 Explanation: “226” could be decoded as “BZ” (2 26), “VF” (22 6), or
“BBF” (2 2 6).

[ ]: # To- Do

0.10 Unique-paths
There is a robot on an m x n grid. The robot is initially located at the top-left corner (i.e.,
grid[0][0]). The robot tries to move to the bottom-right corner (i.e., grid[m - 1][n - 1]). The robot
can only move either down or right at any point in time.
Given the two integers m and n, return the number of possible unique paths that the robot can
take to reach the bottom-right corner.
The test cases are generated so that the answer will be less than or equal to 2 * 109.
Example 1:
Input: m = 3, n = 7 Output: 28

9
Example 2:
Input: m = 3, n = 2 Output: 3 Explanation: From the top-left corner, there are a total of 3 ways
to reach the bottom-right corner: 1. Right -> Down -> Down 2. Down -> Down -> Right 3.
Down -> Right -> Down
[ ]: class Solution:
def uniquePaths(self, m: int, n: int) -> int:
# total m+n ways he can travel
# and m and n are same
# fact(m+n)/(fact(m)*fact(n))
def fact(n):
if n <=0:
return 1
else:
return n*fact(n-1)
return int(fact(m+n-2)/(fact(m-1)*fact(n-1)))

0.11 Jump-game
You are given an integer array nums. You are initially positioned at the array’s first index, and
each element in the array represents your maximum jump length at that position.
Return true if you can reach the last index, or false otherwise.
Example 1:
Input: nums = [2,3,1,1,4] Output: true Explanation: Jump 1 step from index 0 to 1, then 3 steps
to the last index.
Example 2:
Input: nums = [3,2,1,0,4] Output: false Explanation: You will always arrive at index 3 no matter
what. Its maximum jump length is 0, which makes it impossible to reach the last index.
[ ]: class Solution:
def canJump(self, nums: List[int]) -> bool:
n = len(nums)
max_index = 0
for i in range(n-1):
if i <= max_index:
max_index = max(max_index, i + nums[i])
if max_index >= n-1:
return True
return False

10

You might also like