lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. 题目

 

读题

 https://leetcode.cn/problems/unique-paths/

 

考查点

这道题的考查点主要是**动态规划**的思想,也就是把一个复杂的问题分解成多个子问题,用一个数组或矩阵来存储子问题的解,然后通过状态转移方程来求解最终的问题。¹²⁴

动态规划的难点在于找到合适的状态转移方程,也就是如何从已知的子问题的解推导出更大的子问题的解,直到得到最终问题的解。¹²⁴

这道题还可以用**排列组合**的方法来解决,也就是利用数学公式来计算从左上角到右下角需要走多少步,然后在这些步数中选择向下或向右走的步数,求出所有可能的组合数。²

这种方法的难点在于避免溢出,也就是要注意阶乘运算可能会超过整数范围,需要用更大的数据类型或者优化计算过程。²

 

 

2. 解法

思路

 

这道题的解答思路是这样的:

首先,我们可以用一个二维数组dp[m][n]来存储到达每个格子的路径数,初始条件是dp[0][0] = 1,表示从左上角到左上角只有一种路径。

然后,我们可以遍历每个格子,根据它的位置来更新dp数组的值。有三种情况:

  • 如果格子在第一行,那么它只能从左边的格子来,所以dp[i][j] = dp[i][j-1]。
  • 如果格子在第一列,那么它只能从上面的格子来,所以dp[i][j] = dp[i-1][j]。
  • 如果格子在其他位置,那么它可以从左边或上面的格子来,所以dp[i][j] = dp[i-1][j] + dp[i][j-1]。

最后,我们返回dp[m-1][n-1],就是右下角的值,也就是从左上角到右下角的路径数。

代码逻辑

代码的逻辑是这样的:

首先,我们创建一个二维数组dp,用来存储到达每个格子的路径数,初始化为1,表示每个格子都至少有一种路径。

然后,我们用两个嵌套的for循环来遍历每一行和每一列,从第二行和第二列开始,因为第一行和第一列已经初始化了。

对于每个格子,我们判断它是否在第一行或第一列,如果是,那么它只能从左边或上面来,所以我们把左边或上面的值赋给它。如果不是,那么它可以从左边或上面来,所以我们把左边和上面的值相加赋给它。

最后,我们返回dp[m-1][n-1],就是右下角的值,也就是从左上角到右下角的路径数。

 

具体实现

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n]; // 创建二维数组
        dp[0][0] = 1; // 初始条件
        for (int i = 0; i < m; i++) { // 遍历每一行
            for (int j = 0; j < n; j++) { // 遍历每一列
                if (i == 0 && j == 0) continue; // 跳过左上角
                if (i == 0) { // 第一行,只能从左边来
                    dp[i][j] = dp[i][j-1];
                } else if (j == 0) { // 第一列,只能从上面来
                    dp[i][j] = dp[i-1][j];
                } else { // 其他情况,从左边或上面来
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
                }
            }
        }
        return dp[m-1][n-1]; // 返回右下角的值
    }
}

  

 

3. 总结

posted on 2023-05-01 16:45  白露~  阅读(3)  评论(0编辑  收藏  举报