夯实算法-12.不同路径

170 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

题目:LeetCode 【难易度:中等】

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

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

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

示例 1: robot_maze.png

输入: 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

提示:

  • 1 <= m, n <= 100
  • 题目数据保证答案小于等于 2 * 10^9

解题思路

分析题目就可知,就是求不同路径的最大数目,那首先想到的是动态规划问题。但其实也有另外的方法来解决-递归法

解题的关键就是要找出 递归关系式。定义一个函数 dfs(i,j)表示从(0,0)到(i,j)的所有路径数,根据题目提示中的图结合上面设定分函数dfs(i,j),要到达(i, j)这个位置,会有以下两种方式:

  • 从 (i-1, j) 位置走一步到达
  • 从(i, j – 1) 位置走一步到达

那么推算出来递推关系式:dfs(i, j) = dfs(i – 1, j) + dfs(i, j – 1)

接下来就是确定初始值,根据上面推算的递推关系 在dfs(i, j)中如果i=0 或者 j=0,那递推关系就不成立。公式中的i-1或j-1就会出现负数,结合问题场景可以知道i=0或j=0 就是函数边界,此时dfs(i, j) = 1。

但再进一步分析:dfs(i, j) = dfs(i – 1, j) + dfs(i, j – 1) 关系式算出来的有存在重复数据。举例示范一下:(i =4, j=4)时

008i3skNgy1gqmulpfwq9j31mu0pqb29.jpg 可以看到红线圈出来的数据是存在重复情况的,因此用变量要存起来,每次都要判断一下来确保位置是否已存在数据。

代码分析

class Solution {
    // 全局变量,定义二维数组来保存计算好的值
    static int[][] arr = null;
    public int uniquePaths(int m, int n) {
        // 创建一个二维数组
        arr = new int[m][n];
        return dfs(m - 1, n -1);
    }

    public int dfs(int i, int j) {
        if(i == 0 || j == 0){
            return 1;
        }
        // java 中,数组的初始值是 0,所以可以用 arr[i][i] 是否为 0 来判断
        if(arr[i][j] != 0){
            return arr[i][j];
        }
                // 把计算过的值保存起来
        arr[i][j] = dfs(i - 1, j) + dfs(i, j - 1);

        return arr[i][j];
    }
}

这题的主要关键点是找出递推关系和初始值,其余元素就可以被推导出来。

掘金(JUEJIN)  一起分享知识, Keep Learning!