62.不同路径63. 不同路径 II

1|062.不同路径

62.不同路径

// 动态规划清晰步骤: 1. 定义dp数组 2. 初始化 3. 循环填充 4. 返回结果 class Solution { // 也是一个从起点到终点的问题, 1) dp[i][j],表示i,j格子的不同路径数, 2) dp[0][0] = 1 dp[0][1] =1 dp[1][0] = 1 3) dp[i][j] = dp[i-1][j] + dp[i][j-1]; 4) 左上到右下 public int uniquePaths(int m, int n) { // 1. 定义dp数组 int[][] dp = new int[m][n]; // 2. 初始化 for (int i = 0; i < m; i++) dp[i][0] = 1; for (int j = 0; j < n; j++) dp[0][j] = 1; // 3. 循环填充 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]; } } // 4. 返回结果 return dp[m - 1][n - 1]; } } // 动态规划写法2: 内部解决初始化问题 class Solution2 { public int uniquePaths(int m, int n) { int[][] dp = new int[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i == 0 && j != 0) { dp[i][j] = dp[i][j - 1]; } else if (i != 0 && j == 0) { dp[i][j] = dp[i - 1][j]; } else if (i == 0 && j == 0) { dp[i][j] = 1; } else { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } } return dp[m - 1][n - 1]; } } // 深度优先搜索DFS: 可以遍历二叉树, 可以从头到尾遍历每一条路径(更彻底), 但是本题只需要知道多少条路径。所以是充分不必要条件。 // 所有寻路的过程可以连接成一个二叉树, 每个叶子节点说明一条路径 class Solution3 { private int postOrder(int i, int j, int m, int n) { //越界, 不能构成一种可能, 但是在这里也会发现即使不构成可能也会被算法遍历这种可能(产生过搜索),时间复杂度高 // Leetcode中会超时, 可以进行剪枝优化 if (i >= m || j >= n) return 0; // 符合条件的一种可能 if (i == m - 1 && j == n - 1) return 1; int left = postOrder(i + 1, j, m, n); int right = postOrder(i, j + 1, m, n); return left + right; } public int uniquePaths(int m, int n) { return postOrder(0, 0, m, n); } } // 剪枝, LeetCode中还是会超时 class Solution4 { private int postOrder(int i, int j, int m, int n) { // 符合条件的一种可能 if (i == m - 1 && j == n - 1) return 1; int left = 0; int right = 0; if (i + 1 < m) left = postOrder(i + 1, j, m, n); if (j + 1 < n) right = postOrder(i, j + 1, m, n); return left + right; } public int uniquePaths(int m, int n) { return postOrder(0, 0, m, n); } } // 排列组合思路:我们需要移动 (m - 1) + (n - 1)次,其中有 m−1 次向下移动,n−1 次向右移动。因此路径的总数,就等于从 m+n−2 次移动中选择 m−1 次向下移动的方案数,即组合数: // 计算是全排列然后去重

2|063. 不同路径 II

63. 不同路径 II

// 本题很简单, 只需要将62题, dp数组对于障碍物的位置改为0即可: 1. 定义dp数组 2. 初始化 3. 循环填充 4. 返回结果 class Solution { public int uniquePathsWithObstacles(int[][] obstacleGrid) { // 1. 定义dp数组 int m = obstacleGrid.length; int n = obstacleGrid[0].length; int[][] dp = new int[m][n]; // 2. 初始化 if (obstacleGrid[0][0] == 1) return 0; // 打补丁测试用例 dp[0][0] = 1; for (int i = 1; i < m; i++) if (obstacleGrid[i][0] == 0) dp[i][0] = dp[i - 1][0]; for (int j = 1; j < n; j++) if (obstacleGrid[0][j] == 0) dp[0][j] = dp[0][j - 1]; // 3. 循环填充 for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { if (obstacleGrid[i][j] == 0) dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; else dp[i][j] = 0; } } // 4. 返回结果 return dp[m - 1][n - 1]; } }

__EOF__

本文作者Rocky
本文链接https://www.cnblogs.com/nrocky/p/15972656.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   -Rocky-  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示