题目地址:
https://www.lintcode.com/problem/unique-paths-iii/description
给定一个 m m m行 n n n列的二维矩阵 A A A,允许从左上角走到右下角,每一步只能向右或者向下走一步。问所有的不同路径和的总和是多少(也就是说每个不同的路径和累加的时候只加一次)。
思路是动态规划。开 m × n m\times n m×n的HashSet矩阵 f f f, f [ i ] [ j ] f[i][j] f[i][j]存的是从左上角到达 ( i , j ) (i,j) (i,j)为止,所有不同的路径和。这样可以按照最后一步是从哪个方向走的来分类,如果是从上面走的路径,那么可以将集合 f [ i − 1 ] [ j ] + A [ i ] [ j ] f[i-1][j]+A[i][j] f[i−1][j]+A[i][j]的数加入 f [ i ] [ j ] f[i][j] f[i][j],对于从左边走的路径,也可以类似做。最后只需返回 f [ m − 1 ] [ n − 1 ] f[m-1][n-1] f[m−1][n−1]里的数之和。代码如下:
import java.util.HashSet;
import java.util.Set;
public class Solution {
/*
* @param : an array of arrays
* @return: the sum of all unique weighted paths
*/
public int uniqueWeightedPaths(int[][] grid) {
// write your codes here
if (grid.length ==0|| grid[0].length==0) {
return 0;
}
int m = grid.length, n = grid[0].length;
Set<Integer>[][] dp = (Set<Integer>[][]) new HashSet[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
dp[i][j] = new HashSet<>();
if (i == 0 && j == 0) {
dp[i][j].add(grid[i][j]);
} else {
if (i > 1) {
for (int v : dp[i - 1][j]) {
dp[i][j].add(v + grid[i][j]);
}
}
if (j > 1) {
for (int v : dp[i][j - 1]) {
dp[i][j].add(v + grid[i][j]);
}
}
}
}
}
int res = 0;
for (int v : dp[m - 1][n - 1]) {
res += v;
}
return res;
}
}
时空复杂度 O ( ( m + n n ) ) O({{m+n}\choose {n}}) O((nm+n))。