Open azl397985856 opened 1 year ago
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
f = [[0] * n for _ in range(m)]
for i in range(m):
f[i][0] = 1
for i in range(n):
f[0][i] = 1
for i in range(1, m):
for j in range(1,n):
f[i][j] = f[i-1][j] + f[i][j-1]
return f[-1][-1]
class Solution: def uniquePaths(self, m: int, n: int) -> int:
ans = [[0 for _ in range(n)] for _ in range(m)]
ans[0][0] = 1
for i in range(m):
for j in range(n):
if i == 0 and j ==0:
continue
elif i == 0 and j != 0:
ans[i][j] = 1
elif i != 0 and j == 0:
ans[i][j] = 1
else:
ans[i][j] = ans[i-1][j] + ans[i][j-1]
return ans[-1][-1]
class Solution {
public int uniquePaths(int m, int n) {
int[] pre = new int[n];
int[] cur = new int[n];
Arrays.fill(pre, 1);
Arrays.fill(cur,1);
for (int i = 1; i < m;i++){
for (int j = 1; j < n; j++){
cur[j] = cur[j-1] + pre[j];
}
pre = cur.clone();
}
return pre[n-1];
}
}
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector
for(int i = 0; i < n; i++)
dp[m][i] = 0;
for(int j = 0; j < m; j++)
dp[j][n] = 0;
for(int i = m-1; i >= 0; i--)
{
for(int j = n-1; j >= 0; j--)
{
if(i == m-1 && j == n-1)
dp[i][j] = 1;
else
dp[i][j] = dp[i+1][j] + dp[i][j+1];
}
}
return dp[0][0];
}
};
DFS
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
@cache
def dfs(i, j):
if i >= m or j >= n: return 0
if i == m-1 and j == n-1: return 1
return dfs(i+1, j) + dfs(i, j+1)
return dfs(0, 0)
...
class Solution {
public int uniquePaths(int m, int n) {
int[][] f = new int[m][n];
for (int i = 0; i < m; ++i) {
f[i][0] = 1;
}
for (int j = 0; j < n; ++j) {
f[0][j] = 1;
}
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
return f[m - 1][n - 1];
}
}
状态转移方程:(i,j)这个位置只有可能通过(i-1,j)和(i,j-1)两个位置过来。边界的地方可以通过一个位置过来
/**
* @param {number} m
* @param {number} n
* @return {number}
*/
var uniquePaths = function(m, n) {
const dp = Array(m).fill().map(() => Array(n).fill(0))
for (let i = 0; i<m; i++) {
for (let j = 0; j<n; j++) {
if ( i== 0 || j== 0 ) {
dp[i][j] = 1;
} else {
dp[i][j] = dp[i-1][j] + dp[i][j-1]
}
}
}
return dp[m-1][n-1]
};
时间O(nm) 空间O(nm)
code
public int uniquePaths(int m, int n) {
int[] dp = new int[n];
Arrays.fill(dp, 1);
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[j] = dp[j - 1] + dp[j];
}
}
return dp[n - 1];
}
动态规划。题目规定机器人只能向下或向右移动,所以到达最上面一行的任意一个格子只有1种路径(向右走),到达最左边一列的任意一个格子只有1种路径(向下走)。状态转移方程:对于其他格子,可以从该格子的上方格子向下走或左边格子向右走到达,路径数等于上方格子路径数和左边格子路径数之和, path[i][j] = path[i - 1][j] + path[i][j - 1]
。最后返回右下角格子的结果path[m - 1][n - 1]
即可。
class Solution {
public int uniquePaths(int m, int n) {
int[][] path = new int[m][n];
// Base cases:
// top row, can only move left, there is only one way to get to the point
Arrays.fill(path[0], 1);
// left column, can only move down, there is only one way to get to the point
for (int i = 0; i < m; i++) {
path[i][0] = 1;
}
// calculate the path for other points
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
// number of paths for the point = number of paths for the point above it
// + number of paths for the point to the left of it
path[i][j] = path[i - 1][j] + path[i][j - 1];
}
}
return path[m - 1][n - 1];
}
}
复杂度分析
class Solution:
def uniquePaths(self, m: int, n: int):
dp = [[0]*n for _ in range(m)]
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]
class Solution { public int uniquePaths(int m, int n) { if (m == 1 || n == 1) return 1;
int[][] dp = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 1;
}
else {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m - 1][n - 1];
}
}
var uniquePaths = function(m, n) {
// m-1个右,n-1个下
// 相当于有m个空,让n-1个下排雷组合
// C n-1+m-1
// Total permutations = (m+n)! / (m! * n!)
if(m === 1 || n === 1) return 1;
m--; n--;
// Swap, so that m is the bigger number
if(m<n){
m=m+n;
n=m-n;
m=m-n;
}
let res=1;
let j=1;
for(let i=m+1;i<=m+n;i++,j++){
res*=i;
res/=j;
}
return res;
};
(Referring to solution)
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
d = [[1] * n for _ in range(m)]
for col in range(1, m):
for row in range(1, n):
d[col][row] = d[col - 1][row] + d[col][row - 1]
return d[m - 1][n - 1]
(i, j) 的路径数 = (i-1, j) + (i, j-1)
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m, vector<int>(n, 1));
for(int i=1; i<m; i++){
for(int j=1; j<n; j++){
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> ans;
ans[0][0]=0;
for(int i=1;i<m;i++) ans[0][i]=1;
for(int i=1;i<n;i++) ans[i][0]=1;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
ans[i][j]=ans[i-1][j]+ans[i][j-1];
}
}
return ans[m][n];
}
};
class Solution: def uniquePaths(self, m: int, n: int) -> int: pre = [1] n cur = [1] n for i in range(1, m): for j in range(1, n): cur[j] = pre[j] + cur[j-1] pre = cur[:] return pre[-1]
dp[i][j]表示在m,n的网格中,走到i,j的位置上时有dp[i][j]条不同的路径 递推公式:dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 初始值:所有横纵坐标有0的一律为0,有1的一律为1
const dp = new Array(m+1).fill(0).map(() => new Array(n+1).fill(0))
for(let i = 1; i <= m; i++) {
for(let j = 1; j <=n; j++) {
if (i === 1 || j === 1) {
dp[i][j] = 1
} else {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
}
}
}
return dp[m][n]
时间复杂度:O(N^2)
路径问题
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m, vector(n, 0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i == 0 || j == 0) {
dp[i][j] = 1;
} else {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m - 1][n - 1];
}
};
复杂度分析
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> f(m, vector<int>(n));
for (int i = 0; i < m; ++i) {
f[i][0] = 1;
}
for (int j = 0; j < n; ++j) {
f[0][j] = 1;
}
for (int i = 1; i < m; ++i) {
for (int j = 1; j < n; ++j) {
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
}
return f[m - 1][n - 1];
}
};
class Solution {
public int uniquePaths(int m, int n) {
int[][] f = new int[m+1][n+1];
f[1][1] = 1;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (i == 1 && j == 1) continue;
f[i][j] = f[i-1][j] + f[i][j-1];
}
}
return f[m][n];
}
}
dp[i][j]=dp[i-1][j]+dp[i][j-1];
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m,vector<int>(n,1));
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};
O(M∗N)
dp[i][j]表示在m,n的网格中,走到i,j的位置上时有dp[i][j]条不同的路径,dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
class Solution {
public int uniquePaths(int m, int n) {
int[] cur = new int[n];
Arrays.fill(cur,1);
for (int i = 1; i < m;i++){
for (int j = 1; j < n; j++){
cur[j] += cur[j-1] ;
}
}
return cur[n-1];
}
}
时间复杂度:O(n2)
空间复杂度:O(n)
class Solution { public int uniquePaths(int m, int n) { int[] cur = new int[n]; Arrays.fill(cur,1); for (int i = 1; i < m;i++){ for (int j = 1; j < n; j++){ cur[j] += cur[j-1] ; } } return cur[n-1]; } }
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for(int i = 0; i < m; i++){
dp[i][0] = 1;
}
for(int i = 0; i < n; i++){
dp[0][i] = 1;
}
for(int i = 1; i < m; i++){
for(int j = 1; j < n; j++){
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m - 1][n - 1];
}
}
class Solution: def uniquePaths(self, m: int, n: int) -> int:
dp = [[1 for i in range(n)] for j in range(m)]
for i in range(1, m):
for j in range(1, n):
dp[i][j] = dp[i][j - 1] + dp[i - 1][j]
return dp[m - 1][n - 1]
# ###节省空间
cur = [1] * n
for i in range(1, m):
for j in range(1, n):
cur[j] += cur[j-1]
return cur[-1]
Java Code:
class Solution {
public int uniquePaths(int m, int n) {
int[][] res = new int[m][n];
for (int i = 0; i < m; i++) {
res[i][0] = 1;
}
for (int i = 0; i < n; i++) {
res[0][i] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
res[i][j] = res[i - 1][j] + res[i][j - 1];
}
}
return res[m-1][n-1];
}
}
class Solution {
public int uniquePaths(int m, int n) {
// 定义dp
int[] dp = new int[n];
// 遍历
Arrays.fill(dp,1);
for(int i = 1 ; i < m;i++){
for(int j = 1; j < n ; j++){
dp[j] = dp[j] + dp[j - 1];
}
}
return dp[n-1];
}
}
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
cur = [1] * n
for i in range(1, m):
for j in range(1, n):
cur[j] += cur[j-1]
return cur[-1]
动态规划建模
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
d = [[1] * n for _ in range(m)]
for col in range(1, m):
for row in range(1, n):
d[col][row] = d[col - 1][row] + d[col][row-1]
return d[m-1][n-1]
class Solution {
public int uniquePaths(int m, int n) {
// 优化方式
// 第 i 行 第 j 列的可能数目
int[] dp = new int[n];
// 这是第 1(index= 0) 行的数目
Arrays.fill(dp, 1);
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[j] = dp[j] + dp[j - 1];
}
}
return dp[n - 1];
}
}
# 思路
# 1.定义状态:不同路径的数量 dp[i][j]含义:到位置(i, j)一共有几条路径
# 2.初始化状态:初始化第一行和第一列,均为1
# 3.状态转移:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [[1] * n] + [[1] + [0] * (n - 1)] * (m - 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[-1][-1]
动态规划 转移方程为 f(i,j) = f(i-1,j)+f(i,j-1)
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
f = [[1] * n] + [[1] + [0] * (n - 1) for _ in range(m - 1)]
print(f)
for i in range(1, m):
for j in range(1, n):
f[i][j] = f[i - 1][j] + f[i][j - 1]
return f[m - 1][n - 1]
/**
DP: 到当前这个点的 unique path 的数量
因为只能往右或者下, 所以 第一行和第一列 所有的 dp = 1
对于其它 cell, dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
TC: O(MN) SC: O(MN)
*/
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for (int i = 0; i < n; i++) dp[0][i] = 1;
for (int i = 0; i < m; i++) dp[i][0] = 1;
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m - 1][n - 1];
}
}
62. 不同路径
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/unique-paths/
前置知识
暂无
题目描述