62.不同路径
要注意dp的物理含义,是走到dp某一点的路径数量,所以需要初始化横着走和竖着走的dp都为1(横着走到头和竖着走到头只有一种方法)
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp=[[0]*n]*m
for i in range(m):
dp[i][0]=1
for j in range(n):
dp[0][j]=1
for i in range(1,m):
for j in range(1,n):
dp[i][j]=dp[i-1][j]+dp[i][j-1]
return dp[m-1][n-1]
63.不同路径Ⅱ
这道题其实就是上面那道题的升级版,关键点在于怎么处理障碍物。在dp中,我们可以将障碍物(如果在第一行或者第一列)之后的位置不管。在状态转移方程之前,有涉及到障碍物的地方就跳过即可
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
m=len(obstacleGrid)
n=len(obstacleGrid[0])
if obstacleGrid[m-1][n-1]==1 or obstacleGrid[0][0]==1:
return 0
dp=[[0]*n for _ in range(m)]
for i in range(m):
if obstacleGrid[i][0]==0:
dp[i][0]=1
else:
break
for j in range(n):
if obstacleGrid[0][j]==0:
dp[0][j]=1
else:
break #dp构造完成了
for i in range(1,m):
for j in range(1,n):
if obstacleGrid[i][j]==1:
continue
dp[i][j]=dp[i-1][j]+dp[i][j-1]
return dp[m-1][n-1]
343.整数拆分
没有想象中的难,但是状态转移方程/dp[i]中的最大值的种类得想清楚。
class Solution:
def integerBreak(self, n: int) -> int:
dp=[0]*(n+1) #dp[i]指正整数i拆分乘积最大值
dp[0]=0
dp[1]=1
dp[2]=1
for i in range(3,n+1):
for j in range(1,i):
dp[i]=max(dp[i],j*dp[i-j],j*(i-j))
return dp[n]
96.不同的二叉搜索树
先小留一下,等二刷。。。