题目来源: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];
}
}