| |
|
|
开发:
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图书馆 购物 三丰科技 阅读网 日历 万年历 2025年12日历 | -2025/12/20 21:40:34- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |