1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class Solution {
private final int[][] DIRECTIONS = new int[][] { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };
private int mod = 1000000007;

public int countPaths(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
long[][] cache = new long[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
dfs(matrix, i, j, cache);
}
}
long ans = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
ans += cache[i][j];
}
}
return (int) (ans % (mod));

}

private long dfs(int[][] matrix, int row, int col, long[][] cache) {
if (cache[row][col] != 0) {
return cache[row][col];
}
long numOfWays = 1;
for (int[] direction : DIRECTIONS) {
int newRow = row + direction[0];
int newCol = col + direction[1];
if (!isOutOfBound(matrix.length, matrix[0].length, newRow, newCol)
&& matrix[row][col] < matrix[newRow][newCol]) {
numOfWays = (numOfWays + dfs(matrix, newRow, newCol, cache)) % mod;
}
}
cache[row][col] = numOfWays;
return cache[row][col];
}

private boolean isOutOfBound(int rowLength, int colLength, int row, int col) {
return row < 0 || row >= rowLength || col < 0 || col >= colLength;
}
}

这个就是DFS. 递归函数的作用就是给定一个位置, 告诉我们从这个位置出去的increasing path有多少种.

时间复杂度: O(m * n) 因为每个格子最多遍历一次. 我们用cache存储走过的路.
空间复杂度: O(m * n) 我们用cache存东西, 同时DFS用栈.

从某个位置出发的increasing path的个数就是从四周格子出发的总path数目 + 1. + 1是从自己出发, 到自己, 周围的path数 + 1是在从四周出发的每个方案的头一个插入我们那就是从我们这里出发的一种新方案.