LeetCode 62.不同路径

文章目录

  • LeetCode 62.不同路径
    • 传送门
    • 1.题目
    • 2.递归+记忆搜索
      • 思路和解法
      • 代码
    • 2.动态规划
      • 状态转移
      • 代码
    • 3.动态规划压缩空间
      • 优化思路

LeetCode 62.不同路径

传送门

1.题目

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

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

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

示例 1:

LeetCode 62.不同路径_第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

提示:

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

Related Topics

数学

动态规划

组合数学

2.递归+记忆搜索

思路和解法

  1. 首先可以确定机器人的位置,(0,0)。

  2. 然后我们知道机器人要去的位置是(m,n)

  3. 因为机器人只能往右走和下走,所以能确定机器人能走的步数为格子的纵轴长度-1加上横轴长度-1.

  4. 用递归模拟机器人的行驶路线。

    会有如下几种情况

    1)当机器人的的步数为0的时候

    我们可以判断机器人的位置,

    如果在目标位置那么我们可以确定我们找到了一种方法返回1,不在目标位置返回0.

    2)当机器人来到纵轴的底部的时候这个时候只能往右走。

    3)当机器人来到横轴的底部的时候这个时候只能往下走。

    4)当机器人不在2),3)两种极端情况下,那么他既可以往右,也能往下走,递归这两种情况

  5. 因为递归会发生重复情况,所以添加一张缓存表缓存走过的位置。

代码

public int uniquePaths(int m, int n) {
    int[][] dp = new int[m][n];
    return process(m - 1, n - 1, 0, 0, m + n - 2, dp);
}

public int process(int m, int n, int i, int j, int b, int[][] dp) {
    int result;
    if (dp[i][j] != 0) {
        return dp[i][j];
    }
    if (b == 0) {
        result = j == n && i == m ? 1 : 0;
    } else if (i == m) {
        result = process(m, n, i, j + 1, b - 1, dp);
    } else if (j == n) {
        result = process(m, n, i + 1, j, b - 1, dp);
    } else {
        result = process(m, n, i, j + 1, b - 1, dp) + process(m, n, i + 1, j, b - 1, dp);
    }
    dp[i][j] = result;
    return result;
}

2.动态规划

通过递归和dp表我们可以观察到机器人在最下方和最右方只能像一个方向移动,而不处于以上两种极端情况下。

机器人可以往下或者往左移动。

状态转移

所以根据以上结论可以得出状态转移的公式为

dp[i][j] = dp[i + 1][j] + dp[i][j + 1]
当处于边界的情况下
对边界的值设置为1

代码

public static int uniquePaths(int m, int n) {
    int[][] dp = new int[m][n];
    for (int i = 0; i < n; i++) {
        dp[m - 1][i] = 1;
    }
    for (int i = 0; i < m; i++) {
        dp[i][n - 1] = 1;
    }
    for (int i = m - 2; i >= 0; i--) {
        for (int j = n - 2; j >= 0; j--) {
            dp[i][j] = dp[i + 1][j] + dp[i][j + 1];
        }
    }
    return dp[0][0];
}

3.动态规划压缩空间

优化思路

动态规划的空间复杂度是n*n,而我们可以发现我们最后的有效值其实只需要最后的第一行的值

[6][3][1]
[3][2][1]
[1][1][1]

所以可以对空间进行优化,去掉二维数组中的列只保留单个一行的值

public int uniquePaths(int m, int n) {
    int[] dp = new int[n];
    for (int i = 0; i < n; i++) {
        dp[i] = 1;
    }
    for (int i = m - 2; i >= 0; i--) {
        for (int j = n - 2; j >= 0; j--) {
            dp[j] = dp[j] + dp[j + 1];
        }
    }
    return dp[0];
}

你可能感兴趣的:(LeetCode,leetcode,算法,动态规划)