LeetCode 62. Unique Paths(动态规划)

题目来源:https://leetcode.com/problems/unique-paths/

问题描述

62. Unique Paths

Medium

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?

Note: m and n will be at most 100.

Example 1:

Input: m = 3, n = 2

Output: 3

Explanation:

From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:

1. Right -> Right -> Down

2. Right -> Down -> Right

3. Down -> Right -> Right

Example 2:

Input: m = 7, n = 3

Output: 28

------------------------------------------------------------

题意

给定一个m×n的棋盘,机器人一开始在棋盘左上角,且只能向下或向右移动。问机器人移动到右下角有几种不同的路线。

------------------------------------------------------------

思路

最直观的想法是深度优先搜索,但每次搜索要二分岔,且搜索阶段为max(m, n),因此深搜的复杂度为O(2^max(m, n)). 于是想到动态规划,用二维数组dp[i][j]表示从起点走到(i, j)处的不同的路线数量,转移方程为:

dp[i][j] = dp[i-1][j] + dp[i][j-1]

由于需要遍历计算每一个单元格,因此时间复杂度为O(mn).

另外还要注意m==0或n==0的特例。

------------------------------------------------------------

代码

直观写出的代码空间复杂度是O(mn),即根据分析直接开一个二维dp数组。对应代码如下:

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

但仔细分析,其实并不需要二维的dp数组,因为本行的计算只依赖上一行,与再之前的各行没有关系,因此只要开一个一维dp数组就行了,空间复杂度为O(n). 对应代码如下:

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

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/89429991