动态规划
动态规划的重点是:状态转移方程
1、判断子序列
leetcode 392. 判断子序列
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
n= len(s)
m = len(t)
#行数是短的
#列数是长的
if n==0:
return True
if m==0:
return False
if n>m:
return False
d=[ [0] * (m+1) for i in range(n+1)]
for i in range(m+1):
d[0][i]=True
for j in range(1,n+1):
d[j][0]=False
for i in range(1,n+1):
for j in range(1,m+1):
if s[i-1]==t[j-1]:
d[i][j]=d[i-1][j-1]
else:
d[i][j]=d[i][j-1]
return d[n][m]
2、总和最大的连续数列
面试题 16.17. 连续数列
难度简单69
给定一个整数数组,找出总和最大的连续数列,并返回总和。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
if len(nums)==0:
return
if len(nums)==1:
return nums[0]
s=nums[0]
max1=nums[0]
for i in range(1,len(nums)):
if s>0:
s=s+nums[i]
max1=max(max1,s)
else:
s=nums[i]
max1=max(max1,s)
return max1
3、使用最小花费爬楼梯,到达下标n
leetcode:746. 使用最小花费爬楼梯
动态规划:
状态转换方程:
到达下标i和下标i下的花费
d[0]=d[1]=0
d[i]=min(d[i-1]+cost[i],d[i-2]+cost[i])
代码如下:
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
k=len(cost)
res=[]
if k==1:
return cost[0]
if k==2:
return min(cost[0],cost[1])
res.append(0)
res.append(0)
for i in range(2,k+1):
s=min(res[i-2]+cost[i-2],res[i-1]+cost[i-1])
res.append(s)
return res[k]
减小空间复杂度:利用滚动数组
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
k=len(cost)
res=[]
if k==1:
return cost[0]
if k==2:
return min(cost[0],cost[1])
res.append(0)
res.append(0)
pre=0
cur=0
for i in range(2,k+1):
s=min(pre+cost[i-2],cur+cost[i-1])
pre=cur
cur=s
return cur
4、三步爬楼梯
leetcode 面试题 08.01. 三步问题
(1)动态规划
class Solution:
def waysToStep(self, n: int) -> int:
if n==1:
return 1
if n==2:
return 2
if n==3:
return 4
f=[]
f.append(1)
f.append(2)
f.append(4)
base=1e9+7
for i in range(3,n):
s=((((f[i-1])+(f[i-2]))%base)+(f[i-3]))%base
f.append(int(s))
return f[n-1]
(2)滚动数组,不利用进行保存节省空间
class Solution:
def waysToStep(self, n: int) -> int:
if n==1:
return 1
if n==2:
return 2
if n==3:
return 4
f=[]
f.append(1)
f.append(2)
f.append(4)
base=1e9+7
three=1
two=2
one=4
for i in range(3,n):
tmp=int(((((one)+(two))%base)+(three))%base)
three=two
two=one
one=tmp
return tmp
5、买卖股票的最佳时机,只允许一次买入卖出
关键点是找个最小值
代码的如下:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if len(prices)==0:
return 0
max1=0
min1=prices[0]
for i in range(1,len(prices)):
min1=min(prices[i],min1)
max1=max(max1,prices[i]-min1)
return max1
6、区域和检索
leetcode303. 区域和检索 - 数组不可变
(1)暴力解法
class NumArray:
def __init__(self, nums: List[int]):
self.nums=nums
def sumRange(self, i: int, j: int) -> int:
return sum(self.nums[i:j+1])
(2)动态规划
class NumArray:
def __init__(self, nums: List[int]):
self.nums=nums
self.d=[0]*len(self.nums)
if len(self.nums)==0:
return
self.d[0]=self.nums[0]
for i in range(1,len(nums)):
self.d[i]=self.d[i-1]+self.nums[i]
def sumRange(self, i: int, j: int) -> int:
return self.d[j]-self.d[i]+self.nums[i]
# Your NumArray object will be instantiated and called as such:
# obj = NumArray(nums)
# param_1 = obj.sumRange(i,j)