【力扣每日一题】62.不同路径

【力扣每日一题】62.不同路径_第1张图片
这题比较简单,至少能想到动态规划和排列组合两种方法。

方法一:动态规划

明显,到达第 i 行 j 列的点的路劲数为到达第 i-1 行 j 列的路劲数与到达 i 行 j-1 列的路劲数之和。而第一行和第一列的点只有一条路劲,即不停向右或不停向下。
由此,可以使用一个 m*n 维的dp数组进行动态规划,dp[m-1][n-1]即是到达第 m 行 n 列的路劲数。
class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> dp(m, vector<int>(n));
        for (int& num : dp[0]) {
            num = 1;
        }
        for (vector<int>& v : dp) {
            v[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];
    }
};

方法二:排列组合

由于每次只能向右或向下走,因此一共需要走 m+n-2 步,其中向右走 n-1 步,向下走 m-1 步。
因此,我们只需要确定向右(或向下)走的时刻,另一个方向就自然确定了。
所以最终答案即Cm+n-2n-1
不过在实现中可能有点坑。

class Solution {
public:
    int uniquePaths(int m, int n) {
        long long ans(min(m, n));
        n = m^n^ans;
        m = ans;
        ans = 1;
        for (int x = n, y = 1; y < m; ++x, ++y) {
            ans = ans * x / y;
        }
        return ans;
    }
};

在具体的实现中,可以将 n 选为 m , n 中较小的数,这样可以减少计算量。
另外要注意,ans = ans * x / y 不能写为ans *= x / y,因为后者先计算x / y,会产生精度的损失,导致最后结果出错。

你可能感兴趣的:(力扣,动态规划,算法)