[杨小白]_java_leetcode 62. 不同路径

107 阅读3分钟

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

前言

小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!

62. 不同路径

62. 不同路径

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

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

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

示例1

image.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

2.解析

前两天写了斐波那契数、爬楼梯和楼梯最小花费,都分享了两个做法,递归和记忆数组。今天继续复习这一知识点。想看前三题的点下面链接。

# [杨小白]_java_leetcode 509.斐波那契数

# [杨小白]_java_leetcode 70.爬楼梯

# [杨小白]_java_leetcode 746. 使用最小花费爬楼梯

2.1解法(数学法)

这算是一道高中数学题,对于长m宽n的棋盘,从左上角走到右下角,机器人一共要走m + n - 2步,其中n - 1步是向下走,m - 1步是向右走,在高中数学排列组合那一章节,对于这道题的解法就是Cm+n+2n1C^{n - 1}_{m+n+2},进行计算就可以得到答案了。比如

m = 3,n = 7,就是C82C^{2}_{8}=C86C^{6}_{8}=8*7/2=28.

m = 3,n = 3,就是C42C^{2}_{4}=4*3/2=6

2.2解法(记忆数组)

这里用db记忆数组,实现时间复杂度O(n),空间复杂度也是O(n),也完美的解决了栈溢出。

对于第一排和第一列路径只有一条,所以遍历i = 0,和j = 0,令第一排和第一列的值都为1。而后遍历其他空格,空格db[i][j]的值为上方的值加上左方的值,也就是db[i][j] = db[i - 1][j] + db[i][j - 1]。

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

提交排名

image.png

3.结束

三个一维的db数组题,和一个二维的db数组题,这种记录所遍历的值的思想对于每次都要反复去求解有显著优化效果。以后遇到这种每次都要反复求解的题,可以先想想可不可以用记忆数组。对于一维数组,可以进一步优化,因为每一个值只与他的前两个值有关,所以只记录前两个值就可以完成db数组的功能,这也是进一步优化。