1 #62-不同路径
-
题目:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?- 示例1:
输入:m = 3, n = 7 输出:28
- 示例2:
输入:m = 3, n = 2 输出:3 解释: 从左上角开始,总共有 3 条路径可以到达右下角。 1. 向右 -> 向右 -> 向下 2. 向右 -> 向下 -> 向右 3. 向下 -> 向右 -> 向右
- 示例1:
-
分析:
- 分析1:直接调用函数
n行m列说明最终路径里面一定会有n-1个向下的步骤和m-1个向右的步骤。意思就是在m+n-2个步骤的路径上,选n-1个位置来向下走,剩下的位置向右走即可,这个数据量直接调函数即可。 - 分析2:动态规划
用 f ( i , j ) f(i,j) f(i,j)表示从左上角走到 ( x , y ) (x,y) (x,y)的路径数量,其中i和y的范围分别是[0,m)和[0,n)。
每一步只能从向下或者向右移动一步,因此要想走到 ( i , j ) (i, j) (i,j),如果向下走一步,那么会从 ( i − 1 , j ) (i-1, j) (i−1,j) 走过来;如果向右走一步,那么会从 ( i , j − 1 ) (i, j-1) (i,j−1) 走过来。因此可以写出动态规划转移方程: f ( i , j ) = f ( i − 1 , j ) + f ( i , j − 1 ) f(i,j)=f(i−1,j)+f(i,j−1) f(i,j)=f(i−1,j)+f(i,j−1)。
如果 i = 0 i=0 i=0,那么 f ( i − 1 , j ) f(i-1,j) f(i−1,j) 并不是一个满足要求的状态,需要忽略这一项;同理,如果 j = 0 j=0 j=0,那么 f ( i , j − 1 ) f(i,j-1) f(i,j−1) 并不是一个满足要求的状态,需要忽略这一项。
因此初始条件为 f ( 0 , 0 ) = 1 f(0,0)=1 f(0,0)=1,即从左上角走到左上角有一种方法。
- 分析1:直接调用函数
-
答案:
- 答案1:
class Solution: def uniquePaths(self, m: int, n: int) -> int: return comb(m + n - 2, n - 1) # Python中的method方法用于获取从n个项目中选择k个项目(不重复且无顺序)的方法数量。
- 答案2:
class Solution: def uniquePaths(self, m: int, n: int) -> int: dp = [[1]*n] + [[1]+[0] * (n-1) for _ in range(m-1)] #print(dp) 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[-1][-1]
2 #70-爬楼梯
- 题目:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。- 示例1:
输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶
- 分析:
动态规划,和#62相同。 - 答案:
class Solution: def climbStairs(self, n: int) -> int: dp = {} dp[1] = 1 dp[2] = 2 for i in range(3,n+1): dp[i] = dp[i-1] + dp[i-2] return dp[n]
3 #78-子集
- 题目:
给你一个整数数组 nums ,返回该数组所有可能的子集(幂集)。解集不能包含重复的子集。- 示例1:
输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
- 分析:
回溯算法 - 答案:
class Solution: def subsets(self, nums: List[int]) -> List[List[int]]: res = [] n = len(nums) def backtrace(i,tmp): res.append(tmp) for j in range(i,n): backtrace(j+1,tmp+[nums[j]]) backtrace(0,[]) return res