Description:
Given an integer matrix, find the length of the longest increasing path. From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed). Example 1:
Input: nums =
[
[9,9,4],
[6,6,8],
[2,1,1]
]
Output: 4
Explanation: The longest increasing path is [1, 2, 6, 9].
Example 2:
Input: nums =
[
[3,4,5],
[3,2,6],
[2,2,1]
]
Output: 4
Explanation: The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed.
解法:
首先自然而然地想到了对于每一个点采用深度优先的搜索算法,得到以该点为起点的最长路径,然而在这个过程中,其实存在重复搜索的问题而影响了程序的效率。代码跑出来果然超时了。以下为DFS代码: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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69public class Solution {
public int longestIncreasingPath(int[][] matrix) {
if (matrix.length == 0) {
return 0;
}
int row = matrix.length;
int col = matrix[0].length;
int max = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
int cnt = dfs(i, j, matrix, row, col);
if (cnt > max) {
max = cnt;
}
}
}
return max;
}
private int dfs(int i, int j, int[][] matrix, int row, int col) {
Stack s = new Stack();
node start = new node(i, j, matrix[i][j],1);
s.push(start);
node now = start;
int[][] direction = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int cnt = 0;
while (!s.isEmpty()) {
now = (node) s.pop();
int flag = 0;
for (int ii = 0; ii < 4; ii++) {
node next = new node(now.i+ direction[ii][0], now.j + direction[ii][1], -1,1);
if (isvalid(next, row, col) && matrix[next.i][next.j] > now.value) {
next.value = matrix[next.i][next.j];
next.step = now.step + 1;
s.push(next);
flag = 1;
}
}
if(flag == 0){
if(now.step > cnt){
cnt = now.step;
}
}
}
return cnt;
}
private boolean isvalid(node n, int row, int col) {
if (n.i >= 0 && n.i < row && n.j >= 0 && n.j < col ) {
return true;
}
return false;
}
}
class node {
int i;
int j;
int value;
int step = 1;
node(int i, int j, int value,int step) {
this.i = i;
this.j = j;
this.value = value;
this.step = step;
}
}
为解决重复搜索问题,引入动态规划思想,以空间换时间。引入记忆矩阵,改写DFS搜索方法,采用递归的方式进行搜索。代码如下: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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63public class Solution {
public int longestIncreasingPath(int[][] matrix) {
if (matrix.length == 0) {
return 0;
}
int row = matrix.length;
int col = matrix[0].length;
int memory[][] = new int[row][col];
int max = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
int cnt = dfs(i, j, matrix, row, col,memory);
if (cnt > max) {
max = cnt;
}
}
}
return max;
}
private int dfs(int i, int j, int[][] matrix, int row, int col,int[][] memory) {
int maxstep = 1;
if(memory[i][j]>0){
return memory[i][j];
}
node now = new node(i,j,matrix[i][j],0);
int[][] direction = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for (int ii = 0; ii < 4; ii++){
node next = new node(now.i+ direction[ii][0], now.j + direction[ii][1], -1,1);
if (isvalid(next, row, col) && matrix[next.i][next.j] > now.value){
next.value = matrix[next.i][next.j];
int cal = dfs(next.i,next.j,matrix,row,col,memory) + 1;
if(maxstep < cal){
maxstep = cal;
}
}
}
memory[i][j] = maxstep;
return memory[i][j];
}
private boolean isvalid(node n, int row, int col) {
if (n.i >= 0 && n.i < row && n.j >= 0 && n.j < col ) {
return true;
}
return false;
}
}
class node {
int i;
int j;
int value;
int step = 1;
node(int i, int j, int value,int step) {
this.i = i;
this.j = j;
this.value = value;
this.step = step;
}
}
又重写了一遍,这次顺多了
1 | class Solution { |