leetcode——第62题——不同路径

题目:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

class Solution {
// private:
// // 方法一:图论中的深搜。将题目等价为一棵二叉树,叶子的节点就是终点
//     int travel(int i, int j, int m, int n)
//     {
//         // 定义 i 表示左孩子当前的层数,j 表示右孩子当前的层数,注意根节点为第 0 层
//         // 终止条件一:越界了
//         if(i > m || j > n)
//         {
//             return 0;
//         }
//         // 终止条件二:找到了一种方法,也就相当于是找到了叶子节点
//         if(i == m && j == n)
//         {
//             return 1;
//         }
//         // return 的值就是左子树到达终点的方法 与 右子树达到终点的方法 之和
//         return travel(i + 1, j, m, n) + travel(i, j + 1, m, n);
//     }

// public:
//     // 运行超时,这棵树的深度为 m+n-1,则节点个数为 [2的 m + n -1 次方 - 1]
//     // 节点个数表征了时间复杂度:O(2的 m + n -1 次方 - 1)
//     int uniquePaths(int m, int n) 
//     {
//         return travel(1, 1,m, n);
//     }

// // 法二::动态规划
// public:
//     int uniquePaths(int m, int n) 
//     {
//         // 1、确定 dp数组以及下标的含义   i 表示横向, j 表示纵向,
//         // 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  注意要用 for 循环来表征

//         // 4、确定遍历顺序
//         // 根据递推公式看,dp[i][j]都是从上方和左方推导而来,那么从左向右一层层遍历即可

//         // // 使用二维数组 时间复杂度 O(m*n)    空间复杂度 O(m*n)
//         // vector> dp(m, vector(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];

//         // 使用一维数组,或者说成是滚动数组 时间复杂度 O(m*n)    空间复杂度 O(n)
//         vector dp(n, 0);
//         for(int i = 0; i < n; i++)  dp[i] = 1;  //列
//         for(int j = 1; j < m; j++)
//         {
//             for(int i = 1; i < n; i++)
//             {
//                 dp[i] += dp[i - 1];      // 这个方法不太好理解的感觉~~
//             }
//         }
//     }

// 法三::数论方法
/*
分析易得,对m 和n 来说,无论怎么走,走到终点都需要 m+n-2 步
在 m+n-2 步中一定有 m-1 步是要往下走的,不管什么时候向下走,这个数是固定的
因此也就是求有几种走法,
也就将问题转化为:给你 m+n-2 个不同的数,随便取 m-1 个数,有几种取法?
这就转化为一个组合问题了,直接利用组合公式来求解
*/
public:
    int uniquePaths(int m, int n)
    {
        // 利用公式进行计算的过程中,有一个问题需要特别注意,就是需要避免两个int溢出
        // 不能把所有的分子、分母单独算出来之后,在做除法
        // 一定要在计算的过程中,不断除以分母,防止计算过程中的溢出现象
        long long numrator = 1;     // 分子
        int denomintor = m - 1;     // 分母
        int part = m - 1;          
        int total = m + n - 2;
        while(part--)
        {
            numrator *= total;
            total--;
            while(denomintor != 0 && numrator % denomintor == 0)
            {
                numrator /= denomintor;
                denomintor--;
            }
        }
        return numrator;
    }

};

你可能感兴趣的:(#,类型总结之——DP动态规划,算法,动态规划)