代码随想录算法训练营第三十九天|62.不同路径 63. 不同路径 II

目录

LeeCode 62.不同路径 

深度搜索法

动态规划法

数论方法

LeeCode 63. 不同路径 II 


LeeCode 62.不同路径 

62. 不同路径 - 力扣(LeetCode)

深度搜索法

思路:机器人走过的路径可以抽象为一棵二叉树,而叶子节点就是终点,此时问题就可以转化为求二叉树叶子节点的个数。

代码:

class Solution {
private:
	int dfs(int i, int j, int m, int n) {
		if (i > m || j > n) return 0;
		if (i == m && j == n) return 1;
		return dfs(i + 1, j, m ,n) + dfs(i, j + 1, m, n);
	}
public:
    int uniquePaths(int m, int n) {
        return dfs(1, 1, m, n);
    }
};

动态规划法

思路

1.确定dp数组及下标含义:dp[i][j]:表示从(0,0)出发,到(i, j) 有dp[i][j]条不同的路径

2.确定递推公式:由题目可知,dp[i][j] = dp[i - 1][j] + dp[i][j - 1];

3.dp数组如何初始化:dp[i][0] = 1,dp[0][j] = 1;

4.确定遍历顺序:从左到右

5.举例递推dp数组

代码

class Solution {
public:
    int uniquePaths(int m, int n) {
    	vector<vector<int>> dp(m, vector<int>(n, 0));
		for (int i = 0; i < m; i++) dp[i][0] = 1;
		for (int j = 0; j < n; j++) dp[0][j] = 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];
    }
};

数论方法

思路:从起点走到终点共有 m + n - 2 步,其中一定有 m - 1步要向下走。转化为,m + n - 2个不同的数中取m - 1个数的取法个数。

注意:求组合的时候,要防止两个int相乘溢出。 不能把算式的分子和分母都算出来再做除法,而是要在计算分子的时候,不断除以分母。

代码

class Solution {
public:
    int uniquePaths(int m, int n) {
        long long numerator = 1; //分子 
        long denominator = m - 1;//分母 
        int count = m - 1;
        int t = m + n - 2;
        while(count--) {
        	numerator *= (t--);
        	while (denominator != 0 && numerator % denominator == 0){
        		numerator /= denominator;
        		denominator--;
			}
		}
		return numerator;
    }
};

LeeCode 63. 不同路径 II 

63. 不同路径 II - 力扣(LeetCode)

思路

1.确定dp数组及下标含义:dp[i][j]:表示从(0,0)出发,到(i, j) 有dp[i][j]条不同的路径

2.确定递推公式:由题目可知,dp[i][j] = dp[i - 1][j] + dp[i][j - 1](无障碍时)

3.dp数组如何初始化:

vector<vector<int>> dp(m, vector<int>(n, 0));
for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1;
for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) dp[0][j] = 1;

4.确定遍历顺序:从左到右

5.举例递推dp数组

代码

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
    	int m = obstacleGrid.size();
		int n = obstacleGrid[0].size();
		//如果在起点或终点出现障碍,直接返回0 
		if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) {
			return 0;
		}
		vector<vector<int>> dp(m, vector<int>(n, 0));
		for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1;
		for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) dp[0][j] = 1;
		for (int i = 1; i < m; i++) {
			for (int j = 1; j < n; j++) {
				if (obstacleGrid[i][j] == 1) continue;
				dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
			}
		} 
        return dp[m - 1][n - 1];
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_74976519/article/details/130911262