| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> leetcode : [62. 不同路径](https: |leetcode-cn.com/problems/unique-paths/) -> 正文阅读 |
|
[数据结构与算法]leetcode : [62. 不同路径](https: |leetcode-cn.com/problems/unique-paths/) |
leetcode : 62. 不同路径一个机器人位于一个 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? 示例 1: 输入:m = 3, n = 7 输出:28 示例 2: 输入:m = 3, n = 2 输出:3 解释: 从左上角开始,总共有 3 条路径可以到达右下角。 1. 向右 -> 向下 -> 向下 2. 向下 -> 向下 -> 向右 3. 向下 -> 向右 -> 向下 示例 3: 输入:m = 7, n = 3 输出:28 示例 4: 输入:m = 3, n = 3 输出:6 提示:
Related Topics 数学 动态规划 组合数学 思路1:递归每次计算向右和向下的路径和,返回。 经过测试,超时,因为计算的很多重复的点。 class Solution { ? ?private int m; ? ?private int n; ? ?public int uniquePaths(int m, int n) { ? ? ? ?this.m = m; ? ? ? ?this.n = n; ? ? ? ?return fun(1,1); ? } ? ?public int fun(int i, int j){ ? ? ? ?if(i == m && j == n){ ? ? ? ? ? ?return 1; ? ? ? } ? ? ? ?//向右 ? ? ? ?int right = 0; ? ? ? ?if(j < n){ ? ? ? ? ? ?right = fun(i,j+1); ? ? ? } ? ? ? ?//向下 ? ? ? ?int down = 0; ? ? ? ?if(i < m){ ? ? ? ? ? ?down = fun(i+1,j); ? ? ? } ? ? ? ?return right+down; ? } }//超时 思路2:动态规划(从右下角往左上角递归)思路1 的修改,举例说明,要计算P(0,0) = P(1,0)+P(0,1)。我们计算P(1,0)时,需要计算P(1,1)。计算P(0,1)时,也需要计算P(1,1)。导致计算重复,思路1超时。 可以使用动态规划的思路,将递归时计算的P(i,j)保存,如果这个值已经计算出来,那么直接拿出来,如果没计算,再递归,这样每一个位置只会计算一次。 class Solution { ? ?//m ,n表示终点的下标 ? ?private int m; ? ?private int n; ? ?private int[][] dp; ? ?public int uniquePaths(int m, int n) { ? ? ? ?this.m = m-1; ? ? ? ?this.n = n-1; ? ? ? ?dp = new int[m][n]; ? ? ? ?return fun(0,0); ? } ? ?public int fun(int i, int j){ ? ? ? ?if(i == m && j == n){ ? ? ? ? ? ?dp[m][n] = 1; ? ? ? ? ? ?return 1; ? ? ? } ? ? ? ?//向右 如果i,j+1已经计算过 就直接返回 ? ? ? ?int right = 0; ? ? ? ?if(j < n){ ? ? ? ? ? ?right = dp[i][j+1] == 0 ? fun(i,j+1) : dp[i][j+1]; ? ? ? } ? ? ? ?//向下 ? ? ? ?int down = 0; ? ? ? ?if(i < m){ ? ? ? ? ? ?down = dp[i+1][j] == 0 ? fun(i+1,j) : dp[i+1][j]; ? ? ? } ? ? ? ?dp[i][j] = right+down; ? ? ? ?return dp[i][j]; ? } } 解答成功: 执行耗时:0 ms,击败了100.00% 的Java用户 内存消耗:38 MB,击败了30.59% 的Java用户 思路3: 动态规划(从左上角往右上角计算)参考leetcode官方:计算0,0点每一个点的路径和。 分析:P(i,j) = P(i-1,j) + P(i,j-1)
class Solution { ? ?//m ,n表示终点的下标 ? ?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 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]; ? } ? } 解答成功: 执行耗时:0 ms,击败了100.00% 的Java用户 内存消耗:38.3 MB,击败了10.63% 的Java用户 思路4:组合数学从左上角到右下角的过程中,我们需要移动 m+n?2 次,其中有 m?1 次向下移动,n?1 次向右移动。因此路径的总数,就等于从 m+n?2 次移动中选择 m?1 次向下移动的方案数,即组合数:C(m-1,m+n-2) = (m+n-2)(m+n-1).....n/(m-1)(m-2)....1 public int uniquePaths(int m, int n) { ? ?long ans = 1; ? ?int i = n; ? ?int j = 1; ? ?//注意 ans*i可能会越界 需要long解决越界问题 ? ?while (j < m){ ? ? ? ?ans = ans * i / j; ? ? ? ?i++; ? ? ? ?j++; ? } ? ?return (int)ans; |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 16:31:50- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |